您的位置:首页 > 其它

哈希表之闭散列

2018-03-03 15:13 281 查看
动态哈希表的基本操作
 
函数实现部分
 
#include"HT.h"
 
1. 在进行初始化之前,先确定它的容量,必须为素数
2. 然后申请内存空间,初始的空间的状态默认为EMPTY
3. 更新容量和元素个数
void InitHt(HT *ht, int capcity)//初始化哈希表
{
if (ht == NULL)
{
return;
}
capcity = GetPrime(capcity);//获取容量
Elem* ht = (Elem*) malloc(sizeof(Elem)*capcity);//申请内存空间
    for (int i = 0; i <ht->capcity; i++)
{
ht->arr[i].state = EMPTY;
}
ht->size = 0;
ht->capcity = capcity;//更新容量
}
 
 
 
 
 
1. 在插入数据时,首先要找到它所需要插进去的位置,若出现哈希冲突,
有两种解决方法
(1)线性探测
则向后移,移到边界时,则将搜索的标记转倒0处,继续搜寻。
(2)二次探测
2.找到后赋值,并更新size以及status(标记)
 
void Insertht(HT *ht, DataType data)//插入数据
{
assert(ht);
Chekcapcity(ht);
if (ht == NULL)//若为空
{
Buyht(data);
}
if (MAX_SIZE == ht->size)
{
printf("哈希表已满");
return;
}
//找要插入的位置
int pos = 0;
pos = HTfunc(data);
//插入数据
while (EXIST == ht->arr[pos].state)//哈希冲突
{
if (ht->arr[pos].data == data)
return 0;
pos++;
    }
//没有哈希冲突,插入数据
ht->arr[pos].data = data;
ht->arr[pos].state = EXIST;
ht->size++;//更新有效个数大小
if (MAX_SIZE == pos)//找到最右边
{
pos = 0;
}
 
}
 
int HTfunc(DataType data)
{
return (data % 10);
}
1. 在查找时,首先要找到它的起始位置(用哈希函数得出的位置)
2. 首先标记不能为空,并且哈希表不能已经是满的状态,否则会发生死循环
3. 如果起始位置的数值等于要查找的数值,则返回其位置
如果不等于,则发生了冲突,向后移,到边界时,则将位置置为0;
4.若跳出循环,则说明找不到
 
int Find(HT *ht, DataType data)//查找
{
if (ht == NULL)//为空
{
return;
}
//
int pos = 0;
pos = HTfunc(data);
while (EMPTY != (ht)->arr[pos].state&&MAX_SIZE > ht->size)//首先需要它的标记不为空
{
if (ht->arr[pos].data == data)//并且数据相等
{
if (ht->arr[pos].state == EXIST)
return pos;//找到,返回1
}
pos++;
 
if (pos = MAX_SIZE)//找到最右边
{
pos = 0;
}
}
return 0;//找不到
}
1. 利用查找函数得到要删除的位置,如果能找到,则更新其size和status(标记)
2. 如果没有找到,则返回
 
void Delete(HT*ht, DataType data)//删除
{
if (ht == NULL)//为空
{
printf("哈希表已空");
}
//查找要删除的位置
 
int pos = Find(ht, data);
if (Find(ht, data))
{
ht->size--;
  ht->arr[pos].state = DELETE;
 
}
else
 
{
return ;
}
其他函数
int Descovery(HT* ht, int pos)//线性探测
{if (ht == NULL)
{
return;
}
pos++;
if (pos == ht->capcity)
{
pos = 0;
}
return pos;
 
}
unsigned long GetPrime(DataType data)
//获取容量
{
for (i = 0; i < _PrimeSize; i++)
{
if (_PrimeList[i]>data)
{
data = _PrimeList[i];
}
}
return data;
}
int  Descovery2(HT *ht, int pos, int i)//二次探测
{
 
if (ht == NULL)
{
return;
}
pos = pos + 2 * i + 1;
if (ht->capcity < pos)
{
pos = pos % (ht->capcity);
}
return pos;
 
}
int checkcapcity(HT*ht)
{
if (ht == NULL)
{
return;
}
//开辟新的空间
HT pNewht;
if ((ht->size) * 10 / (ht->capcity) > 7)//负载因子决定是否需要扩容
{
InitHt(&pNewht, ht->capcity);
    }
//拷贝元素
for (int i = 0; i < ht->capcity; i++)
{
if (ht->arr[i].state == EXIST)
InsertHt(&pNewht, ht->arr[i].data);
}
//更新新空间
Swap(&pNewht, ht);
return 1;
 
}
 
void Swap(HT *pleft, HT*pright)
{
 
//容量的更新
int capcity = pleft->capcity;
(*pleft)->capcity = pright->capcity;
pright->capcity = capcity;
//空间的更新
Elem *arr = pleft->arr;
pleft->arr = pright->arr;
pright->arr =arr;
}
 
void Destroy(HT*ht)
{
free(ht->arr);
 
}
 
 
 
头文件
#include"stdio.h"
#include "assert.h"
#include "malloc.h"
#include"stddef.h"
 
#ifndef _HT__H_
#define _HT__H_
 
typedef int DataType;
 
 
 
 
typedef enum{ EMPTY, EXIST,DELETE } Status;
 
typedef  struct Elem
{
DataType data;
Status  state;
}Elem;
 
typedef struct HT
{
int capcity;//容量
Elem* arr;
int size;
}HT;
 
#define _PrimeSize  28      
static const unsigned long _PrimeList[_PrimeSize] =
{
53ul, 97ul, 193ul, 389ul, 769ul, 1543ul, 3079ul, 6151ul, 12289ul,
    24593ul, 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, 1572869ul,
    3145739ul, 6291469ul, 12582917ul, 25165843ul, 50331653ul, 100663319ul,
201326611ul, 402653189ul, 805306457ul, 1610612741ul, 3221225473ul, 4294967291ul
};
 
void InitHt(HT *ht,int capcity);//初始化哈希表
int CheckCpcity(HT*ht);//扩容
void InsertHt(HT *ht, DataType data);//插入
int HTfunc(DataType data);//哈希函数
int Find(HT *ht, DataType data);//查找
void Delete(HT*ht, DataType data);//删除
int Descovery(HT* ht, int pos);//线性探测
int Descovery2(HT *ht, int pos, int i);//二次探测
unsigned long GetPrime( DataType data);//获取最大素数
void Swap(HT *pleft, HT* pright);//更新新空间
void Destroy(HT*ht);//销毁哈希表
 
#endif  _HT__H_
 
 
测试函数
 
#include"HT.h"
 
int main()
{
HT ht=NULL;
int arr[] = { 11, 12, 15, 17, 20 };
for (int i = 0; i < MAX_SIZE; i++)
{
InsertHt(&ht,arr[i]);
}
Delete(&ht, 12);
{
 Find(&ht, 13);//查找
Find(&ht, 15);//查找
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: