-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOpenHash.cpp
150 lines (134 loc) · 2.96 KB
/
OpenHash.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#pragma once
#include <iostream>
#include <string>
#include <vector>
using namespace std;
namespace OpenHash
{
template<class T>
class HashFunc{
public:
size_t operator()(const T& val) { return val; }
};
template<>
class HashFunc<string>{
public:
size_t operator()(const string& s){
const char* str = s.c_str();
unsigned int seed = 131; // 31 131 1313 13131 131313
unsigned int hash = 0;
while (*str)
hash = hash * seed + (*str++);
return hash;
}
};
template<class V>
struct HashBucketNode{
HashBucketNode(const V& data)
: _pNext(nullptr), _data(data)
{}
HashBucketNode<V>* _pNext;
V _data;
};
// 本文所实现的哈希桶中key是唯一的
template<class V, class HF = HashFunc<V>>
class HashBucket{
typedef HashBucketNode<V> Node;
typedef Node* PNode;
typedef HashBucket<V, HF> Self;
public:
HashBucket(size_t capacity)
: _table(GetNextPrime(capacity))
, _size(0){}
~HashBucket() { Clear(); }
// 哈希桶中的元素不能重复
Node* Insert(const V& data) {
//检测容量
CheckCapacity();
//计算桶号
size_t bucketNo = HashFunc(data);
//检测是否该元素已存在于链表中
Node* pcur = _table[bucketNo];
while (pcur) {
if (pcur->data == data)
return nullptr;//不允许二次插入
pcur = pcur->_pNext;
}
//不存在则头插
pcur = new Node(data);
pcur->_pNext = _table[bucketNo];
_table[bucketNo] = pcur;
++_size;
return pcur;
}
// 删除哈希桶中为data的元素(data不会重复)
bool Erase(const V& data) {
size_t bucketNo = HashFunc(data);
Node* pcur = _table[bucketNo];
Node* ppre = nullptr;
while (pcur) {
if (data = pcur->_data) {
if (_table[bucketNo] == pcur)
_table[bucketNo] = pcur->_pNext;
else
ppre->_pNext = pcur->_pNext;
delete pcur;
--_size;
return true;
}
ppre = pcur;
pcur = pcur->_pNext;
}
return false;
}
Node* Find(const V& data) {
size_t bucketNo = HashFunc(data);
Node* pcur = _table[bucketNo];
while (pcur) {
if (data = pcur->_data)
return pcur;
pcur = pcur->_pNext;
}
return nullptr;
}
size_t Size()const { return _size; }
bool Empty()const { return 0 == _size; }
void Clear() {
for (inr i = 0; i < _table.capacity(); ++i) {
Node* pcur = _table[i];
while (pcur) {
_table[i] = pcur->_pNext;
delete pcur;
pcur = _table[i];
}
}
_size = 0;
}
size_t BucketCount()const { return _table.capacity(); }
void Swap(Self& ht){
_table.swap(ht._table);
swap(_size, ht._size);
}
private:
size_t HashFunc(const V& data){
return HF()(data) % _table.capacity();
}
void CheckCapacity() {
if (_size == _table.capacity()) {
HashBucket<T> ht(_size * 2);
//转移数据
for (size_t i = 0; i < _table.capacity(); ++i) {
Node* pcur = _table[i];
while (pcur) {
ht.Insert(pcur->_data);
pcur = pcur->_pNext;
}
}
Swap(ht);
}
}
private:
vector<Node*> _table;
size_t _size; // 哈希表中有效元素的个数
};
}