免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4070 | 回复: 0
打印 上一主题 下一主题

PHP实现平衡二叉树(AVL树) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-11-21 16:24 |只看该作者 |倒序浏览
PHP实现平衡二叉树(AVL树)





Php代码
  1. 1.<?php   
  2. 2.    require 'bstOrder.php';   
  3. 3.  
  4. 4.    $test = range(1, 10);   
  5. 5.    //$test = array(3,9,1,4,8,5,7,6,2,10);   
  6. 6.    $tree = new Bst($test, true);   
  7. 7.    //$tree->deleteNode('30');(非平衡树可删除,平衡树的没写删除操作)   
  8. 8.    print_r($tree->getTree());   
  9. 9.?>  
  10. <?php
  11.     require 'bstOrder.php';

  12.     $test = range(1, 10);
  13.     //$test = array(3,9,1,4,8,5,7,6,2,10);
  14.     $tree = new Bst($test, true);
  15.     //$tree->deleteNode('30');(非平衡树可删除,平衡树的没写删除操作)
  16.     print_r($tree->getTree());
  17. ?>
复制代码
bstOrder.php

Php代码
  1. 1.<?php   
  2. 2.    /**  
  3. 3.     * PHP实现二叉排序树  
  4. 4.     * @author zhaojiangwei  
  5. 5.     * @since 2011/11/16 16:29  
  6. 6.     *  
  7. 7.     */  
  8. 8.  
  9. 9.    class Node{   
  10. 10.        private $data;   
  11. 11.        private $left;   
  12. 12.        private $right;   
  13. 13.        private $bf;//平衡度   
  14. 14.  
  15. 15.        public function Node($data = NULL, $bf = 0, $left = NULL, $right = NULL){   
  16. 16.            $this->data = $data;   
  17. 17.            $this->left = $left;   
  18. 18.            $this->right = $right;   
  19. 19.            $this->bf = $bf;   
  20. 20.        }   
  21. 21.  
  22. 22.        public function getBf(){   
  23. 23.            return $this->bf;   
  24. 24.        }   
  25. 25.  
  26. 26.        public function setBf($bf){   
  27. 27.            $this->bf = $bf;   
  28. 28.        }   
  29. 29.  
  30. 30.        public function getData(){   
  31. 31.            return $this->data;   
  32. 32.        }   
  33. 33.  
  34. 34.        public function setData($data){   
  35. 35.            $this->data = $data;   
  36. 36.        }   
  37. 37.  
  38. 38.        public function &getLeft(){   
  39. 39.            return $this->left;   
  40. 40.        }   
  41. 41.  
  42. 42.        public function &getRight(){   
  43. 43.            return $this->right;   
  44. 44.        }   
  45. 45.  
  46. 46.        public function setLeft($left){   
  47. 47.            $this->left = $left;   
  48. 48.        }   
  49. 49.  
  50. 50.        public function setRight($right){   
  51. 51.            $this->right = $right;   
  52. 52.        }   
  53. 53.    }   
  54. 54.  
  55. 55.    class Bst{   
  56. 56.        private $head;//头结点   
  57. 57.        private $data;//初始输入的数据,为数组形式,如array('a','b');   
  58. 58.        private $tag;//查找时设置的前一结点(已无效,没用)   
  59. 59.           
  60. 60.        //$bst:是否创建AVL树   
  61. 61.        public function Bst($data, $bst = FALSE){   
  62. 62.            $this->data = $data;   
  63. 63.            $this->head = NULL;   
  64. 64.               
  65. 65.            if(!$bst){   
  66. 66.                $this->createBst();   
  67. 67.            }else{   
  68. 68.                $this->createBfBst();   
  69. 69.            }   
  70. 70.        }   
  71. 71.  
  72. 72.        public function createBfBst(){   
  73. 73.            foreach($this->data as $value){   
  74. 74.                $this->insertBfNode($this->head, $value);      
  75. 75.            }   
  76. 76.        }   
  77. 77.  
  78. 78.        private function insertBfNode(&$node, $value){   
  79. 79.            if($node == NULL){   
  80. 80.                $node = new Node($value, 0);     
  81. 81.                return TRUE;   
  82. 82.            }else{   
  83. 83.                if($node->getData() > $value){   
  84. 84.                    if(!$this->insertBfNode($node->getLeft(), $value)){   
  85. 85.                        return FALSE;   
  86. 86.                    }   
  87. 87.  
  88. 88.                    switch($node->getBf()){   
  89. 89.                        case 0:   
  90. 90.                            $node->setBf(1);   
  91. 91.                            return TRUE;   
  92. 92.                        case 1:   
  93. 93.                            $this->rightRotate($node);   
  94. 94.                            return FALSE;   
  95. 95.                        case -1:   
  96. 96.                            $node->setBf(0);   
  97. 97.                            return FALSE;   
  98. 98.                    }   
  99. 99.                }elseif($node->getData() < $value){   
  100. 100.                    if(!$this->insertBfNode($node->getRight(), $value)){   
  101. 101.                        return FALSE;   
  102. 102.                    }   
  103. 103.  
  104. 104.                    switch($node->getBf()){   
  105. 105.                        case 0:   
  106. 106.                            $node->setBf(-1);   
  107. 107.                            return TRUE;   
  108. 108.                        case 1:   
  109. 109.                            $node->setBf(0);   
  110. 110.                            return FALSE;   
  111. 111.                        case -1:   
  112. 112.                            $this->leftRotate($node);   
  113. 113.                            return FALSE;   
  114. 114.                    }   
  115. 115.                }else{   
  116. 116.                    return FAlse;   
  117. 117.                }   
  118. 118.            }   
  119. 119.        }   
  120. 120.           
  121. 121.        private function excuteLeft(&$node){   
  122. 122.            $temp = $node;   
  123. 123.            $node = $node->getRight();   
  124. 124.            $temp->setRight($node->getLeft());   
  125. 125.            $node->setLeft($temp);   
  126. 126.        }   
  127. 127.  
  128. 128.        private function excuteRight(&$node){   
  129. 129.            $temp = $node;   
  130. 130.            $node = $node->getLeft();   
  131. 131.            $temp->setLeft($node->getRight());   
  132. 132.            $node->setRight($temp);   
  133. 133.        }   
  134. 134.  
  135. 135.        private function leftRotate(&$node){   
  136. 136.            $right = &$node->getRight();   
  137. 137.            switch($right->getBf()){   
  138. 138.                case 1:   
  139. 139.                    $left = &$right->getLeft();   
  140. 140.                    switch($left->getBf()){   
  141. 141.                        case -1:   
  142. 142.                            $right->setBf(0);   
  143. 143.                            $node->setBf(1);   
  144. 144.                            break;   
  145. 145.                        case 0:   
  146. 146.                            $right->setBf(0);   
  147. 147.                            $node->setBf(0);   
  148. 148.                            break;   
  149. 149.                        case 1:   
  150. 150.                            $right->setBf(-1);   
  151. 151.                            $node->setBf(0);   
  152. 152.                            break;   
  153. 153.                    }   
  154. 154.  
  155. 155.                    $left->setBf(0);   
  156. 156.                    $this->excuteRight($right);   
  157. 157.                    $this->excuteLeft($node);   
  158. 158.                    break;   
  159. 159.                       
  160. 160.                case -1:   
  161. 161.                    $node->setBf(0);   
  162. 162.                    $right->setBf(0);   
  163. 163.                    $this->excuteLeft($node);   
  164. 164.                    break;   
  165. 165.            }   
  166. 166.        }   
  167. 167.  
  168. 168.        private function rightRotate(&$node){   
  169. 169.            $left = &$node->getLeft();   
  170. 170.            switch($left->getBf()){   
  171. 171.                case -1:   
  172. 172.                    $right = &$left->getRight();   
  173. 173.                    switch($right->getBf()){   
  174. 174.                        case -1:   
  175. 175.                            $left->setBf(1);   
  176. 176.                            $node->setBf(0);   
  177. 177.                            break;   
  178. 178.                        case 0:   
  179. 179.                            $left->setBf(0);   
  180. 180.                            $node->setBf(0);   
  181. 181.                            break;     
  182. 182.                        case 1:   
  183. 183.                            $left->setBf(0);   
  184. 184.                            $node->setBf(-1);   
  185. 185.                            break;   
  186. 186.                    }   
  187. 187.                     
  188. 188.                    $right->setBf(0);   
  189. 189.                    $this->excuteLeft($left);   
  190. 190.                    $this->excuteRight($node);   
  191. 191.                    break;   
  192. 192.                case 1:   
  193. 193.                    $node->setBf(0);   
  194. 194.                    $left->setBf(0);   
  195. 195.                    $this->excuteRight($node);   
  196. 196.                    break;   
  197. 197.            }   
  198. 198.        }   
  199. 199.  
  200. 200.        public function createBst(){   
  201. 201.            foreach($this->data as $value){   
  202. 202.                $this->insertNode($value);   
  203. 203.            }   
  204. 204.        }   
  205. 205.  
  206. 206.        //$pre:如果找不到该结点,是否返回前值   
  207. 207.        public function &searchBst(& $node, $key, $pre = FALSE){   
  208. 208.            if($node == NULL){   
  209. 209.                if($pre){   
  210. 210.                    return $this->tag;   
  211. 211.                }else{   
  212. 212.                    return FALSE;   
  213. 213.                }   
  214. 214.            }   
  215. 215.               
  216. 216.            if($key > $node->getData()){   
  217. 217.                $this->tag = $node;   
  218. 218.                return $this->searchBst($node->getRight(), $key, $pre);      
  219. 219.            }elseif($key < $node->getData()){   
  220. 220.                $this->tag = $node;   
  221. 221.                return $this->searchBst($node->getLeft(), $key, $pre);   
  222. 222.            }else{   
  223. 223.                return $node;   
  224. 224.            }   
  225. 225.        }   
  226. 226.  
  227. 227.        public function insertNode($key){   
  228. 228.            if(!$this->head){   
  229. 229.                $this->head = new Node($key);   
  230. 230.            }else{   
  231. 231.                $pre = $this->searchBst($this->head, $key, TRUE);   
  232. 232.                $node = new Node($key);   
  233. 233.                  
  234. 234.                if($pre->getData() > $key){   
  235. 235.                    $pre->setLeft($node);      
  236. 236.                }else{   
  237. 237.                    $pre->setRight($node);   
  238. 238.                }   
  239. 239.            }   
  240. 240.        }   
  241. 241.  
  242. 242.        public function deleteNode($key){   
  243. 243.            $node = &$this->searchBst($this->head, $key);   
  244. 244.               
  245. 245.            if(!$node){   
  246. 246.                return FALSE;      
  247. 247.            }   
  248. 248.  
  249. 249.            if($node->getLeft() == NULL){   
  250. 250.                $node = $node->getRight();   
  251. 251.            }elseif($node->getRight() == NULL){   
  252. 252.                $node = $node->getLeft();   
  253. 253.            }else{   
  254. 254.                $leftBig = &$this->searchLeftBig($node);   
  255. 255.                $node->setData($leftBig->getData());   
  256. 256.                  
  257. 257.                if($leftBig->getLeft()){   
  258. 258.                    $leftBig = $leftBig->getLeft();   
  259. 259.                }   
  260. 260.            }   
  261. 261.        }   
  262. 262.  
  263. 263.        private function &searchLeftBig(& $key){   
  264. 264.            $result = &$key->getLeft();   
  265. 265.  
  266. 266.            while($result){   
  267. 267.                if($result->getRight() == NULL){   
  268. 268.                    return $result;   
  269. 269.                }   
  270. 270.  
  271. 271.                $result = &$result->getRight();   
  272. 272.            }   
  273. 273.        }   
  274. 274.  
  275. 275.        public function getTree(){   
  276. 276.            return $this->head;   
  277. 277.        }   
  278. 278.    }   
  279. 279.?>  
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP