[算法导论]散列表


 

 
#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;
}


 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值