Hashtable是很经常在面试中遇到的数据结构,因为他的O(1)操作时间和O(n)空间

之所以自己写一份是因为:

  • 加深对于hashtable的理解
  • 某些公司面试的时候需要coding.......

开放地址法  Xn=(Xn-1 +b ) % size

理论上b要和size是要精心选择的,不过我这边没有做特别的处理,101的默认size是从c#源代码中抄袭的。。。。

代码尽量简单一点是为了理解方便

hashtable快满的时候扩展一倍空间,数据和标志位还有key 这三个数组都要扩展

删除的时候不能直接删除元素,只能打一个标志(因为用了开放地方方法)

目前只支持string和int类型的key(按位131进制)

非线程安全- 因为这是范例代码

支持泛型

  1. public class Hashtable<T>
  2.  
  3. {
  4. public Hashtable()
  5. {
  6. this.dataArray = new T[this.m];
  7. this.avaiableCapacity = this.m;
  8. this.keyArray = new int[this.m];
  9. for (int i = ; i < this.keyArray.Length; i++)
  10. {
  11. this.keyArray[i] = -;
  12. }
  13. this.flagArray = new bool[this.m];
  14. }
  15.  
  16. private int m = ;
  17.  
  18. private int l = ;
  19.  
  20. private int avaiableCapacity;
  21.  
  22. private double factor = 0.35;
  23.  
  24. private T[] dataArray;
  25.  
  26. private int[] keyArray;
  27.  
  28. private bool[] flagArray;
  29.  
  30. public void Add(string s, T item)
  31. {
  32. if (string.IsNullOrEmpty(s))
  33. {
  34. throw new ArgumentNullException("s");
  35. }
  36.  
  37. if ((double)this.avaiableCapacity / this.m < this.factor)
  38. {
  39. this.ExtendCapacity();
  40. }
  41.  
  42. var code = HashtableHelper.GetStringHash(s);
  43. this.AddItem(code, item, this.dataArray, code, this.keyArray, this.flagArray);
  44. }
  45.  
  46. public T Get(string s)
  47. {
  48. if (string.IsNullOrEmpty(s))
  49. {
  50. throw new ArgumentNullException("s");
  51. }
  52.  
  53. var code = HashtableHelper.GetStringHash(s);
  54. return this.GetItem(code, this.dataArray, code, this.keyArray, this.flagArray);
  55. }
  56.  
  57. private void ExtendCapacity()
  58. {
  59. this.m *= ;
  60. this.avaiableCapacity += this.m;
  61. T[] newItems = new T[this.m];
  62. int[] newKeys = new int[this.m];
  63. bool[] newFlags = new bool[this.m];
  64.  
  65. for (int i = ; i < newKeys.Length; i++)
  66. {
  67. newKeys[i] = -;
  68. }
  69.  
  70. for (int i = ; i < this.dataArray.Length; i++)
  71. {
  72. if (this.keyArray[i] >= && !this.flagArray[i])
  73. {
  74. //var code = HashtableHelper.GetStringHash(s);
  75. this.AddItem(
  76. this.keyArray[i],
  77. this.dataArray[i],
  78. newItems,
  79. this.keyArray[i],
  80. newKeys,
  81. this.flagArray);
  82. }
  83. }
  84. this.dataArray = newItems;
  85. this.keyArray = newKeys;
  86. this.flagArray = newFlags;
  87. // throw new NotImplementedException();
  88. }
  89.  
  90. private int AddItem(int code, T item, T[] data, int hashCode, int[] keys, bool[] flags)
  91. {
  92. int address = code % this.m;
  93. if (keys[address] < )
  94. {
  95. data[address] = item;
  96. keys[address] = hashCode;
  97. this.avaiableCapacity--;
  98. return address;
  99. }
  100. else if (keys[address] == hashCode)
  101. {
  102. if (flags[address])
  103. {
  104. flags[address] = false;
  105. data[address] = item;
  106. return address;
  107. }
  108. throw new ArgumentException("duplicated key");
  109. }
  110. else
  111. {
  112. int nextAddress = address + this.l; //open addressing Xn=Xn-1 + b
  113. return this.AddItem(nextAddress, item, data, hashCode, keys, flags);
  114. }
  115. }
  116.  
  117. private T GetItem(int code, T[] data, int hashCode, int[] keys, bool[] flags)
  118. {
  119. int address = code % this.m;
  120. if (keys[address] < )
  121. {
  122. return default(T);
  123. }
  124. else if (keys[address] == hashCode)
  125. {
  126. if (flags[address])
  127. {
  128. return default(T);
  129. }
  130. return data[address];
  131. }
  132. else
  133. {
  134. int nextAddress = address + this.l; //open addressing Xn=Xn-1 + b
  135. return this.GetItem(nextAddress, data, hashCode, keys, flags);
  136. }
  137. }
  138.  
  139. public void Delete(string s)
  140. {
  141. if (string.IsNullOrEmpty(s))
  142. {
  143. throw new ArgumentNullException("s");
  144. }
  145.  
  146. var code = HashtableHelper.GetStringHash(s);
  147. this.DeleteItem(code, this.dataArray, code, this.keyArray, this.flagArray);
  148. }
  149.  
  150. private void DeleteItem(int code, T[] data, int hashCode, int[] keys, bool[] flags)
  151. {
  152. int address = code % this.m;
  153. if (keys[address] < )
  154. {
  155. return;
  156. //not exist
  157. }
  158. else if (keys[address] == hashCode)
  159. {
  160. if (!this.flagArray[address])
  161. {
  162. flags[address] = true;
  163. this.avaiableCapacity++;
  164. }
  165. }
  166. else
  167. {
  168. int nextAddress = address + this.l; //open addressing Xn=Xn-1 + b
  169. this.DeleteItem(nextAddress, data, hashCode, keys, flags);
  170. }
  171. }
  172. }
  173.  
  174. public class HashtableHelper
  175. {
  176. public static int GetStringHash(string s)
  177. {
  178. if (string.IsNullOrEmpty(s))
  179. {
  180. throw new ArgumentNullException("s");
  181. }
  182.  
  183. var bytes = Encoding.ASCII.GetBytes(s);
  184. int checksum = GetBytesHash(bytes, , bytes.Length);
  185. return checksum;
  186. }
  187.  
  188. public static int GetBytesHash(byte[] array, int ibStart, int cbSize)
  189. {
  190. if (array == null || array.Length == )
  191. {
  192. throw new ArgumentNullException("array");
  193. }
  194.  
  195. int checksum = ;
  196. for (int i = ibStart; i < (ibStart + cbSize); i++)
  197. {
  198. checksum = (checksum * ) + array[i];
  199. }
  200. return checksum;
  201. }
  202.  
  203. public static int GetBytesHash(char[] array, int ibStart, int cbSize)
  204. {
  205. if (array == null || array.Length == )
  206. {
  207. throw new ArgumentNullException("array");
  208. }
  209.  
  210. int checksum = ;
  211. for (int i = ibStart; i < (ibStart + cbSize); i++)
  212. {
  213. checksum = (checksum * ) + array[i];
  214. }
  215. return checksum;
  216. }
  217. }

面试准备 - HashTable 的C#实现 开放地址法的更多相关文章

  1. Hash冲突的线性探测开放地址法

    在实际应用中,无论如何构造哈希函数,冲突是无法完全避免的. 开放地址法 这个方法的基本思想是:当发生地址冲突时,按照某种方法继续探测哈希表中的其他存储单元,直到找到空位置为止.这个过程可用下式描述:  ...

  2. Java解决Hash(散列)冲突的四种方法--开放地址法(线性探测,二次探测,伪随机探测)、链地址法、再哈希、建立公共溢出区

    最近时间有点紧,暂时先放参考链接了,待有时间在总结一下: 查了好多,这几篇博客写的真心好,互有优缺点,大家一个一个看就会明白了: 参考 1. 先看这个明白拉链法(链地址法),这个带源码,很好看懂,只不 ...

  3. 开放地址法实现HashTable

    前注:本文不是讲解Java类库的Hashtable实现原理,而是根据计算机哈希表原理自己实现的一个Hashtable. HashTable内部是用数组存放一个(Key-Value pair)键值对的引 ...

  4. 开放地址法散列表ADT

    数据结构定义如下: typedef unsigned int Index; typedef Index Position; struct HashTbl; typedef struct HashTbl ...

  5. 链地址法实现HashMap

    前注:本文介绍的HashMap并非Java类库的实现.而是根据哈希表知识的一个实现. 上文介绍了开放地址法实现HashTable,它的缺点是对hashCode映射为地址后如果出现重复地址,则会占用其他 ...

  6. C# Dictionary源码剖析---哈希处理冲突的方法有:开放定址法、再哈希法、链地址法、建立一个公共溢出区等

    C# Dictionary源码剖析 参考:https://blog.csdn.net/exiaojiu/article/details/51252515 http://www.cnblogs.com/ ...

  7. java 解决Hash(散列)冲突的四种方法--开放定址法(线性探测,二次探测,伪随机探测)、链地址法、再哈希、建立公共溢出区

    java 解决Hash(散列)冲突的四种方法--开放定址法(线性探测,二次探测,伪随机探测).链地址法.再哈希.建立公共溢出区 标签: hashmaphashmap冲突解决冲突的方法冲突 2016-0 ...

  8. 面试之Hashtable和ConcurrentHashMap

    那么要如何保证HashMap的线程安全呢? 方法有很多,比如使用Hashtable或者Collections.synchronizedMap,但是这两位选手都有一个共同的问题:性能.因为不管是读还是写 ...

  9. java8中哪个类用到了开放地址解决冲突

    hreadlocalmap使用开放定址法解决haah冲突,hashmap使用链地址法解决hash冲突

随机推荐

  1. 20145301&20145321&20145335实验五

    20145301&20145321&20145335实验五 这次实验我的组员为:20145301赵嘉鑫.20145321曾子誉.20145335郝昊 实验内容详见:实验五

  2. Revert R12.1.3 Homepage Layout to Link Style as in R12.1.1 or 11i

    https://blogs.oracle.com/ptian/entry/revert_r12_1_3_homepage Oracle EBS 12.1.3主页的展示方式不太习惯,12.1.3为了展示 ...

  3. 转:python获取linux系统及性能信息

    原文:http://amitsaha.github.io/site/notes/articles/python_linux/article.html In this article, we will ...

  4. Android 高仿微信支付密码输入控件

    像微信支付密码控件,在app中是一个多么司空见惯的功能.最近,项目需要这个功能,于是乎就实现这个功能. 老样子,投篮需要找准角度,变成需要理清思路.对于这个"小而美"的控件,我们思 ...

  5. [Asp.net 开发系列之SignalR篇]专题五:SignalR支持的平台

    SignalR支持多种服务器和客户端配置.此外,每种传输方式都有自身的要求限制:如果某种传输方式不被系统支持,SignalR能够优雅地将故障转移到其他类型的传输方式.关于SignalR所支持的传输方式 ...

  6. 作业三:代码规范、代码复审、PSP

    一.代码规范 我认为我们编写的代码都需要进行规范的操作,因为如果为了图省事情或者为了减少时间去完成这个编程.在最后检验的时候就会出现一些警告,导致你这次编程的代码出现问题,当出现问题的时候你在回头去检 ...

  7. 今天心情好,给各位免费呈上200兆SVN代码服务器一枚,不谢!

    开篇先给大家讲个我自己的故事,几个月前在网上接了个小软件开发的私活,平日上班时间也比较忙,就中午一会儿休息时间能抽出来倒腾着去做点.每天下班复制一份到U盘带回去继续摸索,没多久U盘里躺着的文件列表那叫 ...

  8. js模版引擎handlebars.js实用教程——each-基本循环使用方法

    返回目录 <!DOCTYPE html> <html> <head> <META http-equiv=Content-Type content=" ...

  9. 关于node.js的误会

    昨天写了篇博客,介绍了一下我对node.js的第一次亲密接触后的感受,以为node.js很小众,出乎我意料很多人感兴趣,并且对博客中的细节问题做了评论,最多的是围绕node.js的异步与单线程展开的, ...

  10. React Native01-开始 Windows环境安装配置篇

    转载本文章的童鞋请注明原链接. 查阅文档之类的资料,建议到 http://reactnative.cn/ 本人使用环境Win10. 在阅读本文之前,请了解我们安装React Native之前,要安装P ...