哈希表查找
根据哈希算法填充数据,然后查找的时候首先计算哈希位置,然后对其位置的数据进行查找。
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))