/* 判断素数函数:判断输入值是否为素数
* 返回值:bool型:素数返回true,否则返回false
* 参数:num:需要判断的int型输入
*/
bool isPrime(int num) {
if (num == 2 || num == 3) // 判断是否可以被2或者3整除
return true;
if (num % 6 != 1 && num % 6 != 5) // 除余数为1和5以外都可以被2,3整除
return false;
for (int i = 5; i*i < num; i += 6) // 判断是否可以被余数为1或5的数整除
if (num % i == 0 || num % (i + 2) == 0)
return false;
return true;
}
/* 下一个素数函数:得到输入值的下一个素数
* 返回值:int型:下一给素数
* 参数:num:用于比较的初位素数
*/
int NextPrime(int num) {
int n = num + 1;
while (!isPrime(n)) // 判断下一位是否为素数
{
n++;
}
return n;
}
/* 构建函数:构建一个TheCells,用于储存数据
* 返回值:无
* 参数:tablesize:构建的TheCells的大小
*/
void HashMap::Init(int tablesize) {
if (tablesize < MinTableSize) // 判断输入大小是否合法
{
cout << "哈希表大小过小!" << endl;
return; // 直接返回
}
TableSize = NextPrime(tablesize); // 大小为比输入大的第一个素数
TheCells = new HashEntry[TableSize]; // 申请动态空间
if (TheCells == NULL) // 检测申请是否成功
cout << "申请内存失败!" << endl;
for (int i = 0; i < TableSize; i++) // 初始化储存单元状态
TheCells[i].Info = Empty;
}
/* 查找函数:查找对应的元素,并返回其位置;若不存在此元素,则返回其可以插入的位置(平方探测法)
* 返回值:无
* 参数:key:想要查找的元素
*/
Position HashMap::Find(int key) {
Position CurPos; // 储存元素位置
int CollisionNum = 0; // 储存F(i)
CurPos = Hash(key); // 获取对应元素的初始位置
while(TheCells[CurPos].Info == Legitimate && TheCells[CurPos].Element != key) // 判断是否查找到元素,或其不存在
{
CurPos += 2 * ++CollisionNum - 1; // 查找下一个位置:H(i) = H(0) + F(i); F(i) = i^2
if (CurPos >= TableSize)
CurPos -= TableSize;
}
return CurPos; // 返回对应位置
}
/* 插入函数:插入对应的元素(平方探测法)
* 返回值:无
* 参数:key:想要插入的元素
*/
void HashMap::Insert(int key) {
Position Pos; // 储存插入位置
Pos = Find(key); // 获取插入位置
if (TheCells[Pos].Info != Legitimate) // 判断key是否已经存在
{
TheCells[Pos].Info = Legitimate; // 更改储存单元状态
TheCells[Pos].Element = key;
CurSize++; // 增加已使用单元大小
}
if (CurSize > TableSize / 2) // 判断再散列条件
ReHash();
}
/* 删除函数:删除对应的元素
* 返回值:无
*参数:key:想要删除的元素
*/
void HashMap::Remove(int key) {
Position Pos; // 储存对应元素位置
Pos = Find(key); // 查找对于元素位置
if (TheCells[Pos].Info == Legitimate) // 判断元素是否存在
{
TheCells[Pos].Info = Deleted;
CurSize--; // 减少已使用单元大小
}
}
/* 再散列函数:对HashMap进行再散列操作
* 返回值:无
* 参数:无
*/
void HashMap::ReHash() {
int oldSize = TableSize; // 储存旧HashMap大小
HashEntry *oldCells = TheCells; // 储存旧TheCells
Init(2 * TableSize); // 构建新的TheCells
CurSize = 0;
for (int i = 0; i < oldSize; i++) // 重新插入旧表元素
if (oldCells[i].Info == Legitimate)
Insert(oldCells[i].Element);
delete oldCells; // 删除旧TheCells
oldCells = NULL;
}
参考文献:《数据结构与算法分析——C语言描述》
~~转载请注明出处