转载自: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. typedef struct _HASH_TABLE
  7. {
  8. NODE* value[10];
  9. }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. if(NULL == (pNode = pHashTbl->value[data % 10]))
  7. return NULL;
  8. while(pNode){
  9. if(data == pNode->data)
  10. return pNode;
  11. pNode = pNode->next;
  12. }
  13. return NULL;
  14. }

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. if(NULL == pHashTbl->value[data % 10]){
  7. pNode = (NODE*)malloc(sizeof(NODE));
  8. memset(pNode, 0, sizeof(NODE));
  9. pNode->data = data;
  10. pHashTbl->value[data % 10] = pNode;
  11. return TRUE;
  12. }
  13. if(NULL != find_data_in_hash(pHashTbl, data))
  14. return FALSE;
  15. pNode = pHashTbl->value[data % 10];
  16. while(NULL != pNode->next)
  17. pNode = pNode->next;
  18. pNode->next = (NODE*)malloc(sizeof(NODE));
  19. memset(pNode->next, 0, sizeof(NODE));
  20. pNode->next->data = data;
  21. return TRUE;
  22. }

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. if(NULL == (pNode = find_data_in_hash(pHashTbl, data)))
  8. return FALSE;
  9. if(pNode == pHashTbl->value[data % 10]){
  10. pHashTbl->value[data % 10] = pNode->next;
  11. goto final;
  12. }
  13. pHead = pHashTbl->value[data % 10];
  14. while(pNode != pHead ->next)
  15. pHead = pHead->next;
  16. pHead->next = pNode->next;
  17. final:
  18. free(pNode);
  19. return TRUE;
  20. }

总结:

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

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

【转载】一步一步写算法(之hash表)的更多相关文章

  1. 十一、从头到尾彻底解析Hash 表算法

    在研究MonetDB时深入的学习了hash算法,看了作者的文章很有感触,所以转发,希望能够使更多人受益! 十一.从头到尾彻底解析Hash 表算法 作者:July.wuliming.pkuoliver  ...

  2. Hash表及hash算法的分析

    Hash表中的一些原理/概念,及根据这些原理/概念: 一.       Hash表概念 二.       Hash构造函数的方法,及适用范围 三.       Hash处理冲突方法,各自特征 四.   ...

  3. 一步一步写算法(之prim算法 下)

    原文:一步一步写算法(之prim算法 下) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前两篇博客我们讨论了prim最小生成树的算法,熟悉 ...

  4. 一步一步写算法(之prim算法 中)

    原文:一步一步写算法(之prim算法 中) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] C)编写最小生成树,涉及创建.挑选和添加过程 MI ...

  5. 一步一步写算法(之prim算法 上)

    原文:一步一步写算法(之prim算法 上) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前面我们讨论了图的创建.添加.删除和保存等问题.今 ...

  6. 一步一步写算法(之挑选最大的n个数)

    原文:一步一步写算法(之挑选最大的n个数) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 从一堆数据中挑选n个最大的数,这个问题是网上流传的 ...

  7. 一步一步写算法(之n!中末尾零的个数统计)

    原文:一步一步写算法(之n!中末尾零的个数统计) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 在很多面试的题目中,求n!结果中零的个数也是 ...

  8. 一步一步写算法(之hash表)

    [ 声明:版权全部,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] hash表,有时候也被称为散列表.个人觉得,hash表是介于链表和二叉树之间的一种中间结构.链 ...

  9. 一步一步写平衡二叉树(AVL树)

    平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体,也是第一个引入平衡概念的二叉树.1962年,G.M. Adelson-Velsky 和 E.M. Landis发明了这棵 ...

随机推荐

  1. iOS 渐变提示。Labe自动换行

    UILabel *noticeLabel = [[UILabel alloc]init]; noticeLabel.text = @"当前账号已失效果,已清除当前账号已失效果,已清除当前账号 ...

  2. Revit中如何添加水平仰视平面视图

    在Revit平面视图中视角是俯视视角,但是在一些特殊的情况下,我们可能需要创建仰视视角的平面视图,例如我们需要向上看天花板的灯具布置的时候,下面举例说明添加仰视平面视图的方法. 如图在模型中有一楼板跟 ...

  3. js遍历jsonTree

    var json = [{tcName:"11", children:[{tcName:"22", children:[{tcName:"33&quo ...

  4. error while loading shared libraries: /usr/lib64/libc.so.6: invalid ELF header

    在安装一个程序的时候提示libc.so.6过旧,但是查看libc.so的版本是最新的,于是尝试使用尝试软链接  ln -s /usr/lib64/libc.so /usr/lib64/libc.so. ...

  5. [Aaronyang] 写给自己的WPF4.5 笔记20 [3d课 1/4]

    假设你是高中毕业的,ok,数学知识几何知识中,我们学过  x,y,z   3个轴然后就可以画出形状了. 1. 新建空白窗体,grid换成canvas,然后新增一个Viewport3D元素 3d中显示的 ...

  6. java目录

    1. 在jsp文件或Servlet中,可以通过getServletContext().getRealPath("/")来获取项目根目录的绝对路径. 2. Java桌面程序中,可以通 ...

  7. JS区别不同浏览器(微信、手机等)

    最近一直在忙于自己公司的旅游产品,设计方面太广并且要兼容各种设备和场景,包括PC.Mobile.Pad.还有各种支付.由于微信支付和支付宝存在竞争,所以需要区别不同的浏览器,并且WEB项目还要出现在A ...

  8. 使用ueditor小结

    1. 导入 js: ueditor.config.js ueditor.all.js css/images/plugin: themes lang dialog(可选) third-party(可选) ...

  9. javascript方法 call()和apply()的用法

    先上代码: apply()方法示例 /*定义一个人类*/ function Person(name,age) { this.name=name; this.age=age; } /*定义一个学生类*/ ...

  10. git delete repository