zoukankan      html  css  js  c++  java
  • 【转载】一步一步写算法(之hash表)

    转载自:http://blog.csdn.net/feixiaoxing/article/details/6885657

    【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】


        hash表,有时候也被称为散列表。个人认为,hash表是介于链表和二叉树之间的一种中间结构。链表使用十分方便,但是数据查找十分麻烦;二叉树中的 数据严格有序,但是这是以多一个指针作为代价的结果。hash表既满足了数据的查找方便,同时不占用太多的内容空间,使用也十分方便。

        打个比方来说,所有的数据就好像许许多多的书本。如果这些书本是一本一本堆起来的,就好像链表或者线性表一样,整个数据会显得非常的无序和凌乱,在你找 到自己需要的书之前,你要经历许多的查询过程;而如果你对所有的书本进行编号,并且把这些书本按次序进行排列的话,那么如果你要寻找的书本编号是n,那么 经过二分查找,你很快就会找到自己需要的书本;但是如果你每一个种类的书本都不是很多,那么你就可以对这些书本进行归类,哪些是文学类,哪些是艺术类,哪 些是工科的,哪些是理科的,你只要对这些书本进行简单的归类,那么寻找一本书也会变得非常简单,比如说如果你要找的书是计算机方面的书,那么你就会到工科 一类当中去寻找,这样查找起来也会显得麻烦。

        不知道这样举例你清楚了没有,上面提到的归类方法其实就是hash表的本质。下面我们可以写一个简单的hash操作代码。

        a)定义hash表和基本数据节点

    1. typedef struct _NODE  
    2. {  
    3.     int data;  
    4.     struct _NODE* next;  
    5. }NODE;  
    6.   
    7. typedef struct _HASH_TABLE  
    8. {  
    9.     NODE* value[10];  
    10. }HASH_TABLE;  

        b)创建hash表
    1. HASH_TABLE* create_hash_table()  
    2. {  
    3.     HASH_TABLE* pHashTbl = (HASH_TABLE*)malloc(sizeof(HASH_TABLE));  
    4.     memset(pHashTbl, 0, sizeof(HASH_TABLE));  
    5.     return pHashTbl;  
    6. }  

        c)在hash表当中寻找数据
    1. NODE* find_data_in_hash(HASH_TABLE* pHashTbl, int data)  
    2. {  
    3.     NODE* pNode;  
    4.     if(NULL ==  pHashTbl)  
    5.         return NULL;  
    6.   
    7.     if(NULL == (pNode = pHashTbl->value[data % 10]))  
    8.         return NULL;  
    9.   
    10.     while(pNode){  
    11.         if(data == pNode->data)  
    12.             return pNode;  
    13.         pNode = pNode->next;  
    14.     }  
    15.     return NULL;  
    16. }  

        d)在hash表当中插入数据
    1. STATUS insert_data_into_hash(HASH_TABLE* pHashTbl, int data)  
    2. {  
    3.     NODE* pNode;  
    4.     if(NULL == pHashTbl)  
    5.         return FALSE;  
    6.   
    7.     if(NULL == pHashTbl->value[data % 10]){  
    8.         pNode = (NODE*)malloc(sizeof(NODE));  
    9.         memset(pNode, 0, sizeof(NODE));  
    10.         pNode->data = data;  
    11.         pHashTbl->value[data % 10] = pNode;  
    12.         return TRUE;  
    13.     }  
    14.   
    15.     if(NULL != find_data_in_hash(pHashTbl, data))  
    16.         return FALSE;  
    17.   
    18.     pNode = pHashTbl->value[data % 10];  
    19.     while(NULL != pNode->next)  
    20.         pNode = pNode->next;  
    21.   
    22.     pNode->next = (NODE*)malloc(sizeof(NODE));  
    23.     memset(pNode->next, 0, sizeof(NODE));  
    24.     pNode->next->data = data;  
    25.     return TRUE;  
    26. }  

        e)从hash表中删除数据
    1. STATUS delete_data_from_hash(HASH_TABLE* pHashTbl, int data)  
    2. {  
    3.     NODE* pHead;  
    4.     NODE* pNode;  
    5.     if(NULL == pHashTbl || NULL == pHashTbl->value[data % 10])  
    6.         return FALSE;  
    7.   
    8.     if(NULL == (pNode = find_data_in_hash(pHashTbl, data)))  
    9.         return FALSE;  
    10.   
    11.     if(pNode == pHashTbl->value[data % 10]){  
    12.         pHashTbl->value[data % 10] = pNode->next;  
    13.         goto final;  
    14.     }  
    15.   
    16.     pHead = pHashTbl->value[data % 10];  
    17.     while(pNode != pHead ->next)  
    18.         pHead = pHead->next;  
    19.     pHead->next = pNode->next;  
    20.   
    21. final:  
    22.     free(pNode);  
    23.     return TRUE;  
    24. }  

    总结:

        1、hash表不复杂,我们在开发中也经常使用,建议朋友们好好掌握;

        2、hash表可以和二叉树形成复合结构,至于为什么,建议朋友们好好思考一下?


  • 相关阅读:
    python--模块与包
    内置函数 的总结
    迭代器 生成器 列表推导式 生成器表达式的一些总结
    函数的有用信息 带参数的装饰器 多个装饰器装饰一个函数
    函数名的应用(第一对象) 闭包 装饰器
    动态参数 名称空间 作用域 作用域链 加载顺序 函数的嵌套 global nonlocal 等的用法总结
    函数的初识 函数的返回值 参数
    文件操作 常用操作方法 文件的修改
    遍历字典的集中方法 集合的作用 以及增删查的方法
    计算机硬件的小知识
  • 原文地址:https://www.cnblogs.com/pengdonglin137/p/3201509.html
Copyright © 2011-2022 走看看