当前位置:首页 > PHP教程 > php应用 > 列表

利用PHP实现Hash表功能

发布:smiling 来源: PHP粉丝网  添加日期:2015-12-12 15:00:45 浏览: 评论:0 

Hash算法我们多少会了解一点了,下面来介绍利用php实现Hash表的一个例子,希望这些例子可以给各位带来帮助。

Hash表作为最重要的数据结构之一,也叫做散列表。使用PHP实现Hash表的功能。PHP可以模拟实现Hash表的增删改查。通过对key的映射到数组中的一个位置来访问。映射函数叫做Hash函数,存放记录的数组称为Hash表。

Hash函数把任意长度的和类型的key转换成固定长度输出。不同的key可能拥有相同的hash。

Hash表的时间复杂度为O(1),代码如下:

  1. <?php 
  2.  
  3. class HashTable{ 
  4.     private $arr = array(); 
  5.     private $size = 10; 
  6.     public function __construct(){ 
  7.         //SplFixedArray创建的数组比一般的Array()效率更高,因为更接近C的数组。创建时需要指定尺寸 
  8.         $this->arr = new SplFixedArray($this->size); 
  9.     } 
  10.  
  11.     /** 
  12.      * Description: 简单hash算法。输入key,输出hash后的整数 
  13.      * @param $key 
  14.      * @return int 
  15.      */ 
  16.     private function simpleHash($key){ 
  17.         $len = strlen($key); 
  18.         //key中每个字符所对应的ASCII的值 
  19.         $asciiTotal = 0; 
  20.         for($i=0; $i<$len$i++){ 
  21.             $asciiTotal += ord($key[$i]); 
  22.         } 
  23.         return $asciiTotal % $this->size; 
  24.     } 
  25.  
  26.     /** 
  27.      * Description: 赋值 
  28.      * @param $key 
  29.      * @param $value 
  30.      * @return bool 
  31.      */ 
  32.     public function set($key$value){ 
  33.         $hash = $this->simpleHash($key); 
  34.         $this->arr[$hash] = $value
  35.         return true; 
  36.     } 
  37.  
  38.     /** 
  39.      * Description: 取值 
  40.      * @param $key 
  41.      * @return mixed 
  42.      */ 
  43.     public function get($key){ 
  44.         $hash = $this->simpleHash($key); 
  45.         return $this->arr[$hash]; 
  46.     } 
  47.  
  48.     public function getList(){ 
  49.         return $this->arr; 
  50.     } 
  51.  
  52.     public function editSize($size){ 
  53.         $this->size = $size
  54.         $this->arr->setSize($size); 
  55.     } 
  56. ?> 

下面对我们的HashTable进行测试,代码如下:

  1. <?php 
  2. //测试1 
  3. $arr = new HashTable(); 
  4. for($i=0; $i<15; $i++){ 
  5.     $arr->set('key'.$i'value'.$i); 
  6. print_r($arr->getList()); 
  7. //SplFixedArray Object 
  8. //( 
  9. //    [0] => value14 
  10. //    [1] => value4 
  11. //    [2] => value5 
  12. //    [3] => value6 
  13. //    [4] => value7 
  14. //    [5] => value8 
  15. //    [6] => value10 
  16. //    [7] => value11 
  17. //    [8] => value12 
  18. //    [9] => value13 
  19. //) 
  20. //不同的key可能产生相同的hash值,那么赋值的时候后操作会覆盖前操作。 
  21.  
  22. //测试2 
  23. $arr->editSize(15); 
  24. for($i=0; $i<15; $i++){ 
  25.     $arr->set('key'.$i'value'.$i); 
  26. print_r($arr->getList()); 
  27. //SplFixedArray Object 
  28. //( 
  29. //    [0] => value14 
  30. //    [1] => value4 
  31. //    [2] => value0 
  32. //    [3] => value1 
  33. //    [4] => value2 
  34. //    [5] => value3 
  35. //    [6] => value10 
  36. //    [7] => value11 
  37. //    [8] => value12 
  38. //    [9] => value13 
  39. //    [10] => value14 
  40. //    [11] => value9 
  41. //    [12] => 
  42. //    [13] => 
  43. //    [14] => 
  44. //) 
  45. ?> 

改变了值之后可以存放更多的元素。但是仍然存在不同的key可能产生相同的hash值,那么赋值的时候后操作会覆盖前操作的问题。这种冲突的问题我们来用拉链法解决。

拉链法解决冲突。拉链法解决冲突的做法是将所有的相同Hash值的key放在一个链表中,比如key3和key14在hash之后都是0,那么在数组的键为0的地方存储这两个值,形式是链表。如果不能理解我的文字,请看下面的示例,看一下打印信息就明白了。拉链法是什么,就是链表。

创建一个HashNode类,用来存储key和value的值,并且存储相同hash的另一个元素。在同一条链上,查找越后的元素越费时。时间复杂度为O(n).代码如下:

  1. <?php 
  2. class HashNode{ 
  3.     public $key
  4.     public $value
  5.     public $nextNode
  6.     public function __construct($key$value$nextNode=Null){ 
  7.         $this->key = $key
  8.         $this->value = $value
  9.         $this->nextNode = $nextNode
  10.     } 
  11. class NewHashTable{ 
  12.     private $arr
  13.     private $size = 10; 
  14.     public function __construct(){ 
  15.         $this->arr = new SplFixedArray($this->size); 
  16.     } 
  17.     private function simpleHash($key){ 
  18.         $asciiTotal = 0; 
  19.         $len = strlen($key); 
  20.         for($i=0; $i<$len$i++){ 
  21.             $asciiTotal += ord($key[$i]); 
  22.         } 
  23.         return $asciiTotal % $this->size; 
  24.     } 
  25.     public function set($key$value){ 
  26.         $hash = $this->simpleHash($key); 
  27.         if(isset($this->arr[$hash])){ 
  28.             $newNode = new HashNode($key$value$this->arr[$hash]); 
  29.         }else
  30.             $newNode = new HashNode($key$value, null); 
  31.         } 
  32.         $this->arr[$hash] = $newNode
  33.         return true; 
  34.     } 
  35.     public function get($key){ 
  36.         $hash = $this->simpleHash($key); 
  37.         $current = $this->arr[$hash]; 
  38.         while(!emptyempty($current)){ 
  39.             if($current->key == $key){ 
  40.                 return $current->value; 
  41.             } 
  42.             $current = $current->nextNode; 
  43.         } 
  44.         return NULL; 
  45.     } 
  46.     public function getList(){ 
  47.         return $this->arr; 
  48.     } 
  49. ?> 

对我们新的HashTable进行测试,代码如下:

  1. <?php 
  2. //测试1 
  3. $newArr = new NewHashTable(); 
  4. for($i=0; $i<30; $i++){ 
  5.     $newArr->set('key'.$i'value'.$i); 
  6. print_r($newArr->getList()); 
  7. var_dump($newArr->get('key3')); 
  8. //SplFixedArray Object 
  9. //( 
  10. //    [0] => HashNode Object 
  11. //( 
  12. //    [key] => key23 
  13. //            [value] => value23 
  14. //            [nextNode] => HashNode Object 
  15. //( 
  16. //    [key] => key14 
  17. //                    [value] => value14 
  18. //                    [nextNode] => HashNode Object 
  19. //( 
  20. //    [key] => key3 
  21. //                            [value] => value3 
  22. //                            [nextNode] => 
  23. //                        ) 
  24. // 
  25. //                ) 
  26. // 
  27. //        ) 
  28. // 
  29. //    [1] => HashNode Object 
  30. //( 
  31. //    [key] => key24 
  32. //            [value] => value24 
  33. //            [nextNode] => HashNode Object 
  34. //( 
  35. //    [key] => key15 
  36. //                    [value] => value15 
  37. //                    [nextNode] => HashNode Object 
  38. //( 
  39. //    [key] => key4 
  40. //                            [value] => value4 
  41. //                            [nextNode] => 
  42. //                        ) 
  43. // 
  44. //                ) 
  45. // 
  46. //        ) 
  47. // 
  48. //    [2] => HashNode Object 
  49. //( 
  50. //    [key] => key25 
  51. //            [value] => value25 
  52. //            [nextNode] => HashNode Object 
  53. //( 
  54. //    [key] => key16 
  55. //                    [value] => value16 
  56. //                    [nextNode] => HashNode Object 
  57. //( 
  58. //    [key] => key5 
  59. //                            [value] => value5 
  60. //                            [nextNode] => 
  61. //                        ) 
  62. // 
  63. //                ) 
  64. // 
  65. //        ) 
  66. // 
  67. //    [3] => HashNode Object 
  68. //( 
  69. //    [key] => key26 
  70. //            [value] => value26 
  71. //            [nextNode] => HashNode Object 
  72. //( 
  73. //    [key] => key17 
  74. //                    [value] => value17 
  75. //                    [nextNode] => HashNode Object 
  76. //( 
  77. //    [key] => key6 
  78. //                            [value] => value6 
  79. //                            [nextNode] => 
  80. //                        ) 
  81. // 
  82. //                ) 
  83. // 
  84. //        ) 
  85. // 
  86. //    [4] => HashNode Object 
  87. //( 
  88. //    [key] => key27 
  89. //            [value] => value27 
  90. //            [nextNode] => HashNode Object 
  91. //( 
  92. //    [key] => key18 
  93. //                    [value] => value18 
  94. //                    [nextNode] => HashNode Object 
  95. //( 
  96. //    [key] => key7 
  97. //                            [value] => value7 
  98. //                            [nextNode] => 
  99. //                        ) 
  100. // 
  101. //                ) 
  102. // 
  103. //        ) 
  104. // 
  105. //    [5] => HashNode Object 
  106. //( 
  107. //    [key] => key28 
  108. //            [value] => value28 
  109. //            [nextNode] => HashNode Object 
  110. //( 
  111. //    [key] => key19 
  112. //                    [value] => value19 
  113. //                    [nextNode] => HashNode Object 
  114. //( 
  115. //    [key] => key8 
  116. //                            [value] => value8 
  117. //                            [nextNode] => 
  118. //                        ) 
  119. // 
  120. //                ) 
  121. // 
  122. //        ) 
  123. // 
  124. //    [6] => HashNode Object 
  125. //( 
  126. //    [key] => key29 
  127. //            [value] => value29 
  128. //            [nextNode] => HashNode Object 
  129. //( 
  130. //    [key] => key10 
  131. //                    [value] => value10 
  132. //                    [nextNode] => HashNode Object 
  133. //( 
  134. //    [key] => key9 
  135. //                            [value] => value9 
  136. //                            [nextNode] => 
  137. //                        ) 
  138. // 
  139. //                ) 
  140. // 
  141. //        ) 
  142. // 
  143. //    [7] => HashNode Object 
  144. //( 
  145. //    [key] => key20 
  146. //            [value] => value20 
  147. //            [nextNode] => HashNode Object 
  148. //( 
  149. //    [key] => key11 
  150. //                    [value] => value11 
  151. //                    [nextNode] => HashNode Object 
  152. //( 
  153. //    [key] => key0 
  154. //                            [value] => value0 
  155. //                            [nextNode] => 
  156. //                        ) 
  157. // 
  158. //                ) 
  159. // 
  160. //        ) 
  161. // 
  162. //    [8] => HashNode Object 
  163. //( 
  164. //    [key] => key21 
  165. //            [value] => value21 
  166. //            [nextNode] => HashNode Object 
  167. //( 
  168. //    [key] => key12 
  169. //                    [value] => value12 
  170. //                    [nextNode] => HashNode Object 
  171. //( 
  172. //    [key] => key1 
  173. //                            [value] => value1 
  174. //                            [nextNode] => 
  175. //                        ) 
  176. // 
  177. //                ) 
  178. // 
  179. //        ) 
  180. // 
  181. //    [9] => HashNode Object 
  182. //( 
  183. //    [key] => key22 
  184. //            [value] => value22 
  185. //            [nextNode] => HashNode Object 
  186. //( 
  187. //    [key] => key13 
  188. //                    [value] => value13 
  189. //                    [nextNode] => HashNode Object 
  190. //( 
  191. //    [key] => key2 
  192. //                            [value] => value2 
  193. //                            [nextNode] => 
  194. //                        ) //phpfensi.com 
  195. // 
  196. //                ) 
  197. // 
  198. //        ) 
  199. // 
  200. //) 
  201. //string(6) "value3" 
  202. ?>

Tags: Hash函数 Hash表功能

分享到: