自主编程实现哈希表

       哈希表是种数据结构,它可以提供快速的插入操作和查找操作。哈希表也有一些缺点它是基于数组的,数组创建

后难于扩展,某些哈希表被基本填满时,性能下降得非常严重。这个问题是哈希表不可避免的,即冲突现象:对不同

的关键字可能得到同一哈希地址。


第一次接触哈希表时,它的优点多得让人难以置信。不论哈希表中有多少数据,插入和删除(有时包括侧除)只需 要接近常量的时间即0(1)的时间级。实际上,这只需要几条机器指令。 对哈希表的使用者一一人来说,这是一瞬间的事。哈希表运算得非常快,在计算机程序中,如果需要在一秒种内查 找上千条记录通常使用哈希表(例如拼写检查器)哈希表的速度明显比 快,树的操作通常需要O(N)的时间级。哈希 表不仅速度快,编程实现也相对容易。

哈希表也有一些缺点它是基于数组的,数组创建后难于扩展某些哈希表被基本填满时,性能下降得非常严重,所以程序虽必须要清楚表中将要存储多少数据(或者准备好定期地把数据转移到更大的哈希表中,这是个费时的过程)。 而且,也没有一种简便的方法可以以任何一种顺序〔例如从小到大〕遍历表中 数据项 。如果需要这种能力,就只能选择其他数据结构。 然而如果不需要有序遍历数据,并且可以提前预测数据量的大小。那么哈希表在速度和易用性方面是 无与伦比 的。

说了这么多,都是概念,只有结合代码去理解,才能真正懂得哈希表是如何存储数据的:
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

#define FALSE   0
#define TRUE    1

typedef struct _Node
{
	int nData ; 
	struct _Node * next ;
}Node ;

typedef struct _Hash_Table
{
	Node * value[10] ;   //指针数组
}Hash_table;


//创建hash表
Hash_table *create_hash_table()
{
    Hash_table * pHash = (Hash_table*)malloc(sizeof(Hash_table)) ;
	memset(pHash,0,sizeof(Hash_table)) ;
	return pHash ;	
} 


//在Hash表中寻找数据
Node* find_data(Hash_table* pHash ,int nData)
{
	Node* pNode ;
	if(NULL == pHash)   //若哈希表为空
	{
		return NULL ;
	}
	
	if(NULL == (pNode = pHash->value[nData%10]))   //若哈希表中数组没有该成员,进入if条件句
	{
		return NULL ;
	}
	
	while(pNode)  //当该结构体指针不为空时
	{
		if(nData == pNode->nData )
		{
			return pNode ;   //返回找到数据的结构体的指针
		}
		pNode = pNode->next ;
	}
	
	return NULL ;
	
	
}


//在Hash表中添加数据
bool insert_data(Hash_table * pHash ,int nData)
{
    Node * pNode ;
	if(NULL == pHash)   //判断传入指针是否有效 
	{
		return FALSE ;
	}	
	
	if(NULL ==pHash->value[nData%10])  //判断指针数组中有没有该成员,若没有则进入if条件句中
	{
		pNode = (Node*)malloc(sizeof(Node)) ;
		memset(pNode,0,sizeof(Node)) ;     //清空pNode指向的结构体
		pNode->nData = nData ;
		pHash->value[nData%10] = pNode ;
		return TRUE;
	}
	
	if(NULL != find_data(pHash,nData))  //查找到该数据
	{
		return FALSE ;
	}
	
	pNode = pHash->value[nData%10] ;   //指向该元素所在的链表
	while(NULL != pNode->next)
	{
		pNode = pNode->next ;
	}
	
	pNode->next = (Node*)malloc(sizeof(Node)) ;
	memset(pNode->next,0,sizeof(Node)) ;
	pNode->next->nData = nData ;
	return TRUE ;	
	
} 



//在Hash表中删除数据
bool delete_data(Hash_table* pHash , int nData)
{
	Node* pHead ;
	Node* pNode ;
	
	if(NULL == pHash || NULL == pHash->value[nData%10])
	{
		return FALSE ;
	}
	
	if(NULL == (pNode = find_data(pHash,nData)))   //并未找到该数据
	{
		return FALSE ;
	}
	
	if(pNode == pHash->value[nData%10])  //若找到该数据结点并且是数组成员首个结构体
	{
		pHash->value[nData%10] = pNode->next ;
		free(pNode) ;
		return TRUE ;
	}
	
	pHead = pHash->value[nData%10] ;
	while(pNode != pHead->next)    // 遍历找出所要删除的数据位置
	{
		pHead = pHead->next ;
	}
	pHead->next = pNode->next ;
	free(pNode) ;
	return TRUE ;
	
	
}


//打印哈希表
void show_hash_table(Hash_table* pHash)  
{  
    Node* pNode = NULL;  
    for(int i = 0; i<10; i++)     // 从第一个哈希表元素开始打印,直到最后一个元素  
    {    
        printf("value[%d]:",i) ;		
        for(pNode=pHash->value[i] ; NULL != pNode; pNode=pNode->next)   // 打印下标为i的哈希表元素及该位置所链接的节点  
        {  
            printf("%d    ",pNode->nData) ;
        }  
        printf("\n") ;
    }  
}  


int main()
{
	Hash_table* my_Hash_table ;
	my_Hash_table = create_hash_table() ;    //创建哈希表
	char a[10] ={23,12,67,42,78,91,56,8,32,28}; 
	
	//添加数据
	bool blTemp ;
	for(int i = 0;i<10;i++)
	{
		blTemp = insert_data(my_Hash_table,a[i]) ;
		if(blTemp == FALSE)
		{
			printf("对不起 %d 添加失败\n",a[i]) ;
		}
	}
	
 	//查找数据
	Node* pNode ;
	pNode = find_data(my_Hash_table,81) ;
	if(pNode == NULL)
	{
		printf("未找到该数据!\n");
	}
	else
	{
		printf("成功找到:%d\n",pNode->nData) ;
	}
	
	//删除数据
	blTemp = delete_data(my_Hash_table,12);
	if(blTemp == FALSE)
	{
		printf("对不起 删除失败!\n") ;
	}
	else
	{
		printf("成功删除!\n") ;
	} 
	
	
	//打印哈希表
	show_hash_table(my_Hash_table) ;
	
	return 0 ;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值