您的位置:首页 > 理论基础 > 数据结构算法

哈希表学习总结

2016-04-15 09:37 543 查看
什么是哈希表, 哈希函数, 关键字?

关键字: 用户数据

哈希表(Hash Table): 也叫散列表, 是根据关键码值(Key Value) 直接进行数据访问的数据结构.

哈希函数: 也叫散列函数, 是key和[结果]的一种关系. k = f(k);

哈希表有什么用途?

用于加密算法;

用于数字签名;

用于文件校验.

在实际应用中, 哈希表的查找性能是极好的.

在合理的假设下, 它查找一个元素的平均时间是O(1);

哈希函数的构造方法之除留余数法.

在此方法中, 表长代表所有元素个数, 并不是数组长度.

除留余数法此方法为最常用的构造散列函数方法。

对于散列表长为m的散列函数公式为:

f( key ) = key mod p ( p ≤ m ) (p一般取第一个比m小的质数)

代码如下:

/*======================================================================\
* Author (作者): i.sshe
* Date (日期): 2016/03/26
* Others (其他): 寻找<num的最大质数
\*=======================================================================*/
int generate_mod_value(int num)
{
int i = 0;
int j = 0;
int temp = 0;
int flag = 0;

for (i = num; i > 2; i--)
{
flag = 1;
for (j = 2; j <= i/2; j++)
{
if(i % j == 0) //不是质数
{
flag = 0;
break;
}
}

if (flag == 1)
{
temp = i;
break;
}
}
// temp = i;
if (num < 4)
{
temp = num;
}

printf("除留余数法取得的mod值为:%d\n", temp);

return temp;
}


哈希表解决冲突方法之 拉链法(链接法/链地址法)

可以使用单链表或双链表, 双链表更方便删除.

代码如下:

相关结构:

/*=========================================================================*\
* #struct# *
\*=========================================================================*/
typedef struct HASH_NODE_S_
{
int data;
struct HASH_NODE_S_ *prev;
struct HASH_NODE_S_ *next;
}HASH_NODE_S;

typedef struct HASH_TABLE_S_
{
HASH_NODE_S *hash_node;
}HASH_TABLE_S;


创建hash-table操作(create):

HASH_TABLE_S *create_hash_table(int len, int num)
{
HASH_TABLE_S *hash_table = NULL;
int i = 0;
int tempvalue = 0;

hash_table = (HASH_TABLE_S *)malloc(len * sizeof(HASH_TABLE_S));
if (hash_table == NULL)
{
printf("hash table malloc error!\n");
exit(1);
}
memset(hash_table, 0, len * sizeof(HASH_TABLE_S));

//还要增加用户输入数据, 重复的需要链接到后面
printf("请输入数据:\n");
for (i = 0; i < num; i++)
{
scanf("%d", &tempvalue);
insert_element(hash_table, len, tempvalue);
}

return hash_table;
}


插入操作:

先查看表中是否已经存在此元素, 不存在 插入.

int insert_element(HASH_TABLE_S *hash_table, int hash_len, int value)
{
int position_num = value % hash_len;
HASH_NODE_S *node ;

if (search_element(hash_table, hash_len, value))
{
return 0;
}

node = (HASH_NODE_S *)malloc(sizeof(HASH_NODE_S));
if (node == NULL)
{
printf("insert element malloc error!\n");
exit(1);
}

node->data = value;

if (hash_table[position_num].hash_node != NULL) //冲突了
{
node->next = hash_table[position_num].hash_node;
hash_table[position_num].hash_node->prev = node;
hash_table[position_num].hash_node = node;
node->prev = NULL;
}
else
{
hash_table[position_num].hash_node = node;
}

return 1;
}


删除操作(delete):

删除操作要注意删除元素在对应的key下的链表中的位置.(分首个/中间/最后一个三种)

int delete_element(HASH_TABLE_S *hash_table, int mod_value, int value)
{
HASH_NODE_S *current_node = NULL;
int position_key = value % mod_value;

current_node = hash_table[position_key].hash_node;
while (current_node != NULL)
{
if (current_node->data == value)
{
//此元素的第一个元素
if (current_node->prev == NULL && current_node->next != NULL)
{
hash_table[position_key].hash_node = current_node->next;
current_node->next->prev = NULL;
}
else if (current_node->prev != NULL && current_node->next == NULL)
{
// 此元素是最后一个元素
current_node->prev->next = NULL;
}
else if(current_node->prev != NULL && current_node->next != NULL)
{
//此元素是中间的元素
current_node->prev->next = current_node->next;
current_node->next->prev = current_node->prev;
}
else
{
//只剩一个元素
hash_table[position_key].hash_node = NULL;
}

free(current_node);
printf("删除成功!\n");
return 1;
}
current_node = current_node->next;
}

printf("没有此元素!\n");
return 0;

}


勿在浮沙筑高台.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息