二叉搜索树BStree

二叉搜索树,实际上是有点类似于二分查找。实际上很简单,就是递归。直接上代码,有点要注意的就是删除的时候,如果是左子树和右子树都存在的话,要寻找继承者(successor).

 

  1 import java.util.HashMap;
  2 import java.util.Map;
  3 import java.util.Stack;
  4 
  5 public class BSTreeComparable<T extends Comparable> {
  6 
  7     private transient Node root;
  8 
  9     private static final String SUCCESSOR="successor";
 10 
 11     private static final String SUCCESSOR_PARENT="parent";
 12 
 13     private static final Node EMPTY_NODE = new Node(null,null,null,"empty node");
 14 
 15     public BSTreeComparable() { //初始化为一个空树
 16         root = null;
 17     }
 18 
 19     /**
 20      * 查询数据方法
 21      * @param key
 22      * @return
 23      */
 24     public Node get(T key){
 25         if(root ==null) return null;
 26         Node node =  getRecursive(root,key);
 27         if(node ==null) return  EMPTY_NODE;
 28         return node;
 29     }
 30 
 31     /**
 32      * 往BST中插入数据
 33      * @param key
 34      * @param value
 35      */
 36     public  void put(T key,Object value){
 37         if (root == null){
 38             root =  new Node(null,null,key,value);
 39         }else{
 40             putRecursive(root,key,value);
 41         }
 42 
 43 
 44 
 45     }
 46 
 47     public void remove(T key){
 48        Node newTree = remove(root,key);
 49        root = newTree;
 50     }
 51 
 52     private Node remove(Node tree ,T key){
 53         if(tree==null) return null;
 54 
 55         //先递归去找到这个节点
 56         if (key.compareTo(tree.key) < 0) {
 57             tree.leftNode = remove(tree.leftNode, key);
 58             return tree;
 59         }
 60         else if (key.compareTo(tree.key) > 0) {
 61             tree.rightNode = remove(tree.rightNode, key);
 62             return tree;
 63         }// 相等说明已经找到这个节点了
 64         else{
 65             //case 1 假如这个节点左子树为空,则右子树顶包
 66             if (tree.leftNode == null && tree.rightNode!=null) {
 67                 Node rightTree = tree.rightNode;
 68                tree=null;
 69                 return rightTree;
 70             }
 71             //case 2 假如这个节点右子树为空,则左子树顶包
 72             else if (tree.rightNode == null&& tree.leftNode!=null){
 73                 Node leftTree = tree.leftNode;
 74                 tree=null;
 75                 return  leftTree;
 76                 //case 3 是叶子节点
 77             }else if(tree.rightNode == null&& tree.leftNode==null){
 78                 tree=null;    return  null;
 79 
 80             }
 81             //case 4 假如这个节点左右子树都不为空,则找到右子树种的最小值顶包
 82             else{
 83                 Node toBeDeleted = tree;
 84                 Map map = getSuccessor(tree.rightNode,null);
 85                 Node successor = (Node) map.get(SUCCESSOR);
 86                 Node successorParent = (Node) map.get(SUCCESSOR_PARENT);
 87                 //如果successorParent是null的话,说明successor就是右节点
 88                 if(successorParent==null){
 89                     successor.leftNode = toBeDeleted.leftNode;
 90                     tree=null;
 91                     toBeDeleted =null;
 92                     return   successor;
 93                 }else{
 94                     successor.leftNode = toBeDeleted.leftNode;
 95                     successor.rightNode = toBeDeleted.rightNode;
 96                     successorParent.leftNode =null;
 97                     tree=null;
 98                     toBeDeleted =null;
 99                     return successor;
100                 }
101             }
102         }
103     }
104 
105 
106 
107 
108     private Map<String,Node> getSuccessor(Node tree,Map<String,Node> map) {
109         if (map == null) {
110             map =  new HashMap<>();
111         }
112         if (tree.leftNode == null){
113             map.put(SUCCESSOR,tree);
114             return map;
115         }
116         map.put(SUCCESSOR_PARENT,tree);
117         Map<String,Node> map2 =  getSuccessor(tree.leftNode,map);
118         return map2;
119     }
120 
121     private Node  putRecursive(Node tree,T key,Object value){
122         if(tree==null) return new Node(null,null,key,value);
123         if(key.compareTo(tree.key)<0){
124             tree.leftNode = putRecursive(tree.leftNode,key,value);
125         }else if(key.compareTo(tree.key)>0){
126             tree.rightNode = putRecursive(tree.rightNode,key,value);
127         }else{
128             tree.content = value;
129         }
130         return tree;
131     }
132 
133 
134     /**
135      * 递归比较大小,如果小于该节点,则拿左节点继续比较
136      * 如果大于该节点,就拿右节点继续比较
137      * @param tree
138      * @param key
139      * @return
140      */
141     private Node getRecursive(Node tree,T key){
142         if(tree==null) return null;
143         if(key.compareTo(tree.key)<0){
144             return getRecursive(tree.leftNode,key);
145         }else if(key.compareTo(tree.key)>0){
146             return getRecursive(tree.rightNode,key);
147         }else{
148             return tree;
149         }
150     }
151 
152 
153 
154 
155 
156 
157     public static int getHeight(Node root) {
158 
159         if (root == null) {
160             return 0;
161         }
162         int leftHeight = 0;//记录左子树的树高
163         int rightHeight = 0;//记录右子树树高
164         if (root.leftNode != null) {//左子树不为空
165             leftHeight += getHeight(root.leftNode) + 1;//实际就是左子树树高的累计,加上root节点,如果不加1,得到的就是最大子树的树高,不好root节点
166         }
167         if (root.rightNode != null) {
168             rightHeight += getHeight(root.rightNode) + 1;
169         }
170         return leftHeight >= rightHeight ? leftHeight : rightHeight;
171     }
172     public void displayTree(){
173         Stack globalStack = new Stack();
174         globalStack.push(root);
175         int treeHeight = getHeight(root);
176         int nBlanks = (int) Math.pow(2d,(double)treeHeight);
177         boolean isRowEmpty = false;
178         System.out.println("=========================================================================");
179         while(!isRowEmpty) {
180             Stack localStack = new Stack();
181             isRowEmpty = true;
182             for (int  j =0;j<nBlanks;j++) {
183                 System.out.print(" ");
184             }
185 
186             while (!globalStack.isEmpty()) {
187                 Node temp = (Node)globalStack.pop();
188                 if (temp!=null) {
189                     System.out.print(temp.key);
190                     localStack.push(temp.leftNode);
191                     localStack.push(temp.rightNode);
192                     if (temp.leftNode != null || temp.rightNode !=null) {
193                         isRowEmpty = false;
194                     }
195                 }
196                 else {
197                     System.out.print("--");
198                     localStack.push(null);
199                     localStack.push(null);
200                 }
201                 for (int j = 0;j<nBlanks*2-2;j++) {
202                     System.out.print(" ");
203                 }
204             }
205             System.out.println();
206             nBlanks /= 2;
207             while (!localStack.isEmpty()) {
208                 globalStack.push(localStack.pop());
209             }
210         }
211         System.out.println("=========================================================================");
212     }
213 
214     static final class Node<T>{
215         public Node leftNode;
216         public Node rightNode;
217         public T key;
218         public Object content;
219 
220         public Node(Node leftNode, Node rightNode, T key, Object content) {
221             this.leftNode = leftNode;
222             this.rightNode = rightNode;
223             this.key = key;
224             this.content = content;
225         }
226     }
227 }

下面是测试代码:

 1 public class BSTreeComparableTest {
 2     public static void main(String[] args) {
 3         BSTreeComparable tree = new BSTreeComparable();
 4         tree.put(20,"20");
 5         tree.put(10,"10");
 6         tree.put(7,"7");
 7         tree.put(4,"4");
 8         tree.put(30,"30");
 9         tree.put(40,"40");
10         tree.put(14,"14");
11         tree.put(12,"12");
12         tree.put(15,"15");
13         //tree.remove(12);
14         //tree.remove(30);
15         //tree.remove(7);
16         tree.remove(10);
17        tree.displayTree();
18     }
19 }

 觉得写的好的,点个赞,谢谢,大冬天晚上,很辛苦的(◔◡◔)

posted @ 2018-12-07 00:03  sadamu0912  阅读(258)  评论(0)    收藏  举报