您的位置:首页 > 其它

算法导论——散列表

2018-03-17 12:52 239 查看
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
using namespace std;
const int Length = 6;//待插入的数列长度
const int TableSize = 11;//哈希表的容量 应该打大于数列长度以保证每个元素都有处可放

typedef struct Hash{
int data;
Hash *next;
}*HashTable, HashNode;

void InitTable(int num[], int tablesize);
void HashInsert1(int num[], int data[], int size, int len);//开放定址法
void HashInsert2(HashTable num[], int data[], int len, int tablesize);//拉链法

int HashSearch1(int num[], int tablesize, int key);//哈希查找 开放地址法
int HashSearch2(HashTable num[], int tablesize, int key);//哈希查找 拉链法

void Output(int num[], int length);

int main ()
{
int data[Length] = {12, 2, 34, 56, 26, 8};
int num1[TableSize];
InitTable(num1, TableSize);//建造哈希表 进行初始化
HashInsert1(num1, data, TableSize, Length);
Output(num1, TableSize);

HashTable num2[TableSize];
HashInsert2(num2, data, Length, TableSize);

int key = 8;//在表中查找值为key的元素
printf("\n开放寻址法\n");
if(HashSearch1(num1, TableSize, key))
printf("%d 存在于表中", key);
else
printf("查找失败");

printf("\n\n拉链法:\n");
if(HashSearch2(num2, TableSize, key))
printf("%d 存在于表中", key);
else
printf("查找失败");

}

void InitTable(int num[], int tablesize)
{
for(int i = 0; i < tablesize; i++)//对哈希表进行初始化
num[i] = 0;
}

//运用除法散列法 h(k)=k mod m
void HashInsert1(int num[], int data[], int tablesize, int len)
{
int k;
for(int i = 0; i < len; i++)
{
k = data[i] % tablesize;//在这里将哈希函数定义为 %tablesize
if(num[k] == 0)//=0代表此处有空位 可以直接放入
num[k] = data[i];
else//没有空位时 即发生冲突 就要向后移动
{
while(num[k] != 0)//处理冲突的方法:开放寻址法
{
k = (k + 1) % tablesize;
}
num[k] = data[i];
}
}
}
//与插入操作时相同原理
int HashSearch1(int num[], int tablesize, int key)
{
if(num[key % tablesize] == key)
return 1;
else
{
int k = key % tablesize;
while(num[k] != 0)//开放寻址法 若是查找到某位的值为0 则证明查找失败
{
k++;
if(num[k] == key)
return 1;
}
return 0;
}
}

//拉链法的思想就是 将索引相同的元素连接到同一个节点上  因此在查找时不需要对查找地址进行改变 而只需要在该地址上不断后移
int HashSearch2(HashTable num[], int tablesize, int key)
{
if(num[key % tablesize]->data == key)//查找成功
return 1;

else
{
while(num[key % tablesize])//当num[key & tablesize]为空的时候就意味着查找失败了
{
if(num[key % tablesize]->data == key)
return 1;
num[key % tablesize]= num[key % tablesize]->next;//在该节点上不断后移
}
}
}

void HashInsert2(HashTable num[], int data[], int len, int tablesize)
{
int k;
for(int i = 0; i < tablesize; i++)
{
num[i] = (HashTable )malloc(sizeof(HashNode));//需要对每个元素单独分配空间!!!
num[i]->data = 0;//进行初始化
num[i]->next = NULL;
}
for(int i = 0; i < len; i++)
{
k = data[i] % tablesize;//在这里将哈希函数定义为 %tablesize
if(num[k]->data == 0)//=0代表此处有空位 可以直接放入
num[k]->data = data[i];
else
{
HashTable  node = (HashTable )malloc(sizeof(HashNode));//说明在该位置上已经有节点了 因此需要进行新节点的建立
node->data = data[i];//采用头插法 尾插法的话要进行遍历找到尾部元素
node->next = num[k]->next;
num[k]->next = node;
}
}
}

void Output(int num[], int len)
{
for(int i=0; i<len; i++)
{
printf("%d  ", num[i]);
}
cout << endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息