3. 基础查找算法——哈希表查找(golang)

本文介绍了哈希表查找的基本原理,通过哈希算法确定数据存储位置,查找时直接定位,提高了查找效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


哈希表查找

根据哈希算法填充数据,然后查找的时候首先计算哈希位置,然后对其位置的数据进行查找。


const (

	// 数据已经被删除
	Deleted = iota

	// 哈希表的大小
	MintableSize = 100

	// 已经存在的合法数据
	legimate = iota

	// 数据为空
	Empty = iota
)

// 哈希函数(自定义的,不可靠)
func MySHA(str interface{}, tableSize int) int {

	hashvar := 0
	var chars []byte

	// 传入值转为字符串
	if strings, ok := str.(string); ok {

		// 字符串转为字节数组
		chars = []byte(strings)
	}

	// 遍历字节数组
	for _, v := range chars {
		// 哈希算法
		hashvar = (hashvar<<17 | 123&1235 ^ 139) + int(v)
	}

	return hashvar % MintableSize
}

func MySHA256(str interface{}, tableSize int) int {

	// 创建加密对象
	shaObj := sha256.New()

	// 哈希
	shaObj.Write([]byte(str.(string)))

	// 加密后的字节数组
	myChars := shaObj.Sum(nil)

	hashvar := 0

	// 遍历字节数组
	for _, v := range myChars {
		// 哈希算法
		hashvar = (hashvar<<17 | 123&1235 ^ 139) + int(v)
	}

	return hashvar % MintableSize
}

func MySHA512(str interface{}, tableSize int) int {

	// 创建加密对象
	shaObj := sha512.New()

	// 哈希
	shaObj.Write([]byte(str.(string)))

	// 加密后的字节数组
	myChars := shaObj.Sum(nil)

	hashvar := 0

	// 遍历字节数组
	for _, v := range myChars {
		// 哈希算法
		hashvar = (hashvar<<17 | 123&1235 ^ 139) + int(v)
	}

	return hashvar % MintableSize
}

// 函数指针
type HashFunc func(data interface{}, tableSize int) int

// 哈希表元素
type HashEntry struct {
	// 数据
	data interface{}
	// 类型
	kind int
}

// 哈希表
type HashTable struct {
	// 数据
	Cells []*HashEntry
	// 表大小
	tableSize int
	// 调用哈希函数
	hashfunc HashFunc
}

// 哈希表接口
type HashtableGO interface {
	// 查找数据
	Find(data interface{}) int
	// 插入数据
	Insert(data interface{})
	// 清空
	Clear()
	// 抓取value
	GetValue(index int) interface{}
}

// 初始化哈希表
func NewHashTable(size int, hash HashFunc) (*HashTable, error) {

	// 传入表大小,小于限定值
	if size < MintableSize {
		return nil, errors.New("哈希表太小")
	}

	// 没有传哈希函数
	if hash == nil {
		return nil, errors.New("没有哈希函数")
	}

	// 创建哈希表
	hashtable := new(HashTable)

	// 设置哈希表大小
	hashtable.tableSize = size

	// 数组分配内存
	hashtable.Cells = make([]*HashEntry, size)

	// 设置哈希函数
	hashtable.hashfunc = hash

	// 对每个单元进行初始化处理
	for i := 0; i < hashtable.tableSize; i++ {
		hashtable.Cells[i] = new(HashEntry)
		hashtable.Cells[i].data = nil
		// 设置为空
		hashtable.Cells[i].kind = Empty
	}

	return hashtable, nil
}

// 查找
func (ht *HashTable) Find(data interface{}) int {

	// 计算哈希位置
	curpos := ht.hashfunc(data, ht.tableSize)

	// 没找到
	if ht.Cells[curpos].kind != Empty && ht.Cells[curpos].data != data {

		// 平方探测
		curpos := 2*curpos - 1

		// 越界,返回
		if curpos > ht.tableSize {
			curpos -= ht.tableSize
		}

	}
	return curpos
}

// 插入
func (ht *HashTable) Insert(data interface{}) {

	// 查找数据位置
	pos := ht.Find(data)

	// 插入数据
	entry := ht.Cells[pos]

	// 记录状态
	if entry.kind != legimate {
		entry.kind = legimate
		entry.data = data
	}
}

// 清空
func (ht *HashTable) Clear() {

	// 循环清空数据
	for i := 0; i < ht.tableSize; i++ {
		if ht.Cells[i] == nil {
			continue
		}
		// 删除数据
		ht.Cells[i].kind = Deleted
	}
}

// 获取值
func (ht *HashTable) GetValue(index int) interface{} {

	// 越界
	if index > ht.tableSize {
		return nil
	}

	// 取出数据
	entry := ht.Cells[index]

	// 返回
	if entry.kind == legimate {
		return entry.data
	} else {
		return nil
	}
}


// 使用
mytable, _ := NewHashTable(100, HashTableArray.MySHA512)
mytable.Insert("abcd1")
mytable.Insert("abcd2")
mytable.Insert("abcd3")
mytable.Insert("abcd4")
mytable.Insert("abcd")

pos := mytable.Find("abcd1")
fmt.Println(mytable.GetValue(pos))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值