二叉搜索树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 }
觉得写的好的,点个赞,谢谢,大冬天晚上,很辛苦的(◔◡◔)