数据结构-二叉搜索树Java实现

1,Node.java

生成基础二叉树的结构html

 1 package com.cnblogs.mufasa.searchTree;  2 
 3 /**
 4  * 节点配置父+左+右  5  */
 6 public class Node{  7  Node parent;  8  Node leftChild;  9  Node rightChild; 10     int val; 11     public Node(Node parent, Node leftChild, Node rightChild,int val) { 12         super(); 13         this.parent = parent; 14         this.leftChild = leftChild; 15         this.rightChild = rightChild; 16         this.val = val; 17  } 18 
19     public Node(int val){ 20         this(null,null,null,val); 21  } 22 
23     public Node(Node node,int val){ 24         this(node,null,null,val); 25  } 26 }
View Code

图1 Node.java结构java

 

2,SearchBinaryTree.java

在原有二叉树的结构上,进行搜索二叉树的功能扩充:node

①数据增长:递归版本插入、迭代版本ide

②数据删除:this

③数据查找:spa

④数据遍历:前中后code

 1 package com.cnblogs.mufasa.searchTree;  2 
 3 
 4 
 5 public class SearchBinaryTree {  6 
 7     private Node root;  8     private int size;  9     public SearchBinaryTree() {  10         super();  11  }  12 
 13     /**
 14  * 增长节点  15  * @param val  16  * @return
 17      */
 18     public boolean add(int val) {  19         if(root == null){//初始节点为空
 20             root = new Node(val);  21             size++;  22             return true;  23  }  24         //初始节点不为空
 25         Node node = getAdapterNode(root, val);  26         Node newNode = new Node(val);  27         if(node.val > val){  28             node.leftChild = newNode;  29             newNode.parent = node;  30         }else if(node.val < val){  31             node.rightChild = newNode;  32             newNode.parent = node;  33         }else{  34             return false;//增长数据和搜索二叉树中原有数据相同不符合基本限定条件
 35  }  36         size++;  37         return true;  38  }  39 
 40     /**
 41  * 获取最合适的插入节点  42  * @param node  43  * @param val  44  * @return
 45      */
 46     private Node getAdapterNode(Node node,int val){  47         //该节点为空
 48         if(node == null){  49             return node;  50  }  51 
 52         // 往左子树中插入,但没左子树,则返回
 53         if(node.val > val && node.leftChild == null){  54             return node;  55  }  56 
 57         // 往右子树中插入,但没右子树,也返回
 58         if(node.val < val && node.rightChild == null){  59             return node;  60  }  61 
 62         // 该节点是叶子节点,则返回
 63         if(node.leftChild == null && node.rightChild == null){  64             return node;  65  }  66 
 67         //节点能够继续向下,直接递归调用
 68         if(node.val > val && node.leftChild != null){  69             return getAdapterNode(node.leftChild, val);  70         }else if(node.val < val && node.rightChild != null){  71             return getAdapterNode(node.rightChild, val);  72         }else{  73             return node;  74  }  75  }  76 
 77     /**
 78  * 进行迭代增长元素  79  * @param val  80  * @return
 81      */
 82     public boolean put(int val){  83         return putVal(root,val);  84  }  85 
 86     /**
 87  *直接循环搜索目标节点进行数据增长  88  * @param node  89  * @param val  90  * @return
 91      */
 92     private boolean putVal(Node node,int val){  93         if(node == null){// 初始化根节点
 94             node = new Node(val);  95             root = node;  96             size++;  97             return true;  98  }  99         //节点非空
100         Node temp = node; 101  Node p; 102         int t; 103         /**
104  * 经过do while循环迭代获取最佳节点, 105          */
106         do{ 107             p = temp; 108             t = temp.val-val; 109             if(t > 0){ 110                 temp = temp.leftChild; 111             }else if(t < 0){ 112                 temp = temp.rightChild; 113             }else{ 114                 temp.val = val;//增长数据和搜索二叉树中原有数据相同不符合基本限定条件
115                 return false; 116  } 117         }while(temp != null); 118 
119         Node newNode = new Node(p, val); 120         if(t > 0){ 121             p.leftChild = newNode; 122         }else if(t < 0){ 123             p.rightChild = newNode; 124  } 125         size++; 126         return true; 127  } 128 
129     /**
130  * 节点删除 131  * @param val 132  * @return
133      */
134     public boolean delete(int val){ 135         Node node = getNode(val); 136         if(node == null){//没有该节点
137             return false; 138  } 139         Node parent = node.parent; 140         Node leftChild = node.leftChild; 141         Node rightChild = node.rightChild; 142 
143         //如下全部子节点为空的状况,则代表删除的节点是【叶节点】
144         if(leftChild == null && rightChild == null){//没有子节点
145             if(parent != null){ 146                 if(parent.leftChild == node){ 147                     parent.leftChild = null; 148                 }else if(parent.rightChild == node){ 149                     parent.rightChild = null; 150  } 151             }else{//不存在父节点,则代表删除节点为【根节点】,直接返回空
152                 root = null; 153  } 154             node = null; 155             return true; 156 
157         }else if(leftChild == null && rightChild != null){// 只有右节点
158             if(parent != null && parent.val > val){// 存在父节点,且node位置为父节点的左边
159                 parent.leftChild = rightChild; 160             }else if(parent != null && parent.val < val){// 存在父节点,且node位置为父节点的右边
161                 parent.rightChild = rightChild; 162             }else{//父节点不存在!!!
163                 root = rightChild; 164  } 165             node = null; 166             return true; 167 
168         }else if(leftChild != null && rightChild == null){// 只有左节点
169             if(parent != null && parent.val > val){// 存在父节点,且node位置为父节点的左边
170                 parent.leftChild = leftChild; 171             }else if(parent != null && parent.val < val){// 存在父节点,且node位置为父节点的右边
172                 parent.rightChild = leftChild; 173             }else{//父节点不存在!!!
174                 root = leftChild; 175  } 176             node = null; 177             return true; 178 
179         }else if(leftChild != null && rightChild != null){// 两个子节点都存在,至关于直接替换节点
180             Node successor = getSuccessor(node);// 这种状况,必定存在后继节点
181             int temp = successor.val; 182             boolean delete = delete(temp); 183             if(delete){ 184                 node.val = temp; 185  } 186             successor = null; 187             return true; 188  } 189         return false; 190  } 191 
192     /**
193  * 194  * @param node 195  * @return
196      */
197     private Node getSuccessor(Node node){ 198         if(node.rightChild != null){//确定不为空
199             Node rightChild = node.rightChild; 200             while(rightChild.leftChild != null){//不断的向左转向搜索数值
201                 rightChild = rightChild.leftChild; 202  } 203             return rightChild; 204  } 205         //右节点为空这个不存在啊!!!
206         Node parent = node.parent; 207         while(parent != null && (node == parent.rightChild)){ 208             node = parent; 209             parent = parent.parent; 210  } 211         return parent; 212  } 213 
214 
215     /**
216  * 搜索节点 217  * @param val 218  * @return
219      */
220     public Node getNode(int val){ 221         Node temp = root; 222         int t; 223         do{//直接使用循环遍历的方法
224             t = temp.val-val; 225             if(t > 0){ 226                 temp = temp.leftChild; 227             }else if(t < 0){ 228                 temp = temp.rightChild; 229             }else{ 230                 return temp; 231  } 232         }while(temp != null); 233         return null; 234  } 235 
236     /**
237  * 节点删除 238  * @param val 239  * @return
240      */
241     public boolean remove(int val){ 242         Node node = getNode(val); 243         if(node == null){ 244             return false; 245  } 246 
247         if(node.leftChild == null){// 一、左节点不存在,右节点可能存在,包含两种状况 ,两个节点都不存在和只存在右节点
248  transplant(node, node.rightChild); 249         }else if(node.rightChild == null){//二、左孩子存在,右节点不存在
250  transplant(node, node.leftChild); 251         }else{// 三、两个节点都存在
252             Node successor = getSuccessor(node);// 获得node后继节点
253             if(successor.parent != node){// 后继节点存在node的右子树中。
254                 transplant(successor, successor.rightChild);// 用后继节点的右子节点替换该后继节点
255                 successor.rightChild = node.rightChild;// 将node节点的右子树赋给后继节点的右节点,即相似后继与node节点调换位置
256                 successor.rightChild.parent = successor;// 接着上一步 给接过来的右节点的父引用复制
257  } 258  transplant(node, successor); 259             successor.leftChild = node.leftChild; 260             successor.leftChild.parent = successor; 261  } 262         return true; 263  } 264     /**
265  * 将child节点替换node节点 266  * @param node 要删除的节点 267  * @param child node节点的子节点 268      */
269     private void transplant(Node node,Node child){ 270         /**
271  * 一、先判断 node是否存在父节点 272  * 一、不存在,则child替换为根节点 273  * 二、存在,则继续下一步 274  * 二、判断node节点是父节点的那个孩子(即判断出 node是右节点仍是左节点), 275  * 得出结果后,将child节点替换node节点 ,即若node节点是左节点 则child替换后 也为左节点,不然为右节点 276  * 三、将node节点的父节点置为child节点的父节点 277          */
278 
279         if(node.parent == null){ 280             this.root = child; 281         }else if(node.parent.leftChild == node){ 282             node.parent.leftChild = child; 283         }else if(node.parent.rightChild == node){ 284             node.parent.rightChild = child; 285  } 286         if(child != null){ 287             child.parent = node.parent; 288  } 289  } 290 
291     public void print(int type){//方法的重载
292         if(type==0){//前序
293  printPre(root); 294         }else if(type==1){ 295  printMid(root); 296         }else if(type==2){ 297  printEnd(root); 298  } 299  } 300 
301     private void printPre(Node root){//前序遍历
302         if(root != null){ 303             System.out.println(root.val);// 位置在中间,则中序,若在前面,则为先序,不然为后续
304  printPre(root.leftChild); 305  printPre(root.rightChild); 306  } 307  } 308 
309     private void printMid(Node root){//中序遍历
310         if(root != null){ 311  printMid(root.leftChild); 312             System.out.println(root.val);// 位置在中间,则中序,若在前面,则为先序,不然为后续
313  printMid(root.rightChild); 314  } 315  } 316 
317     private void printEnd(Node root){//后序遍历
318         if(root != null){ 319  printEnd(root.leftChild); 320  printEnd(root.rightChild); 321             System.out.println(root.val);// 位置在中间,则中序,若在前面,则为先序,不然为后续
322  } 323  } 324 
325 }
View Code

 

图2 SearchBinaryTree.java结构htm

 

3,JavaDemo.java

 1 package com.cnblogs.mufasa.searchTree;  2 
 3 public class JavaDemo {  4     public static void main(String[] args) {  5         SearchBinaryTree tree=new SearchBinaryTree();  6         tree.add(5);  7         tree.add(1);  8         tree.add(100);  9         tree.add(50); 10         tree.add(22); 11         tree.add(48); 12         tree.print(2); 13  } 14 }
View Code

 

4,特别鸣谢

http://www.javashuo.com/article/p-fzqsjgqb-bo.htmlblog

相关文章
相关标签/搜索