排序二叉树(Search Tree 简称BST):又称二叉搜索树,首先是满足二叉树,二叉树就是每个结点最多有2个子结点,其特点是:它的左结点的值必须小于它的根结点的值,它的右结点的值必须大于它的根结点的值,比如5,3,7,1,4,6,8。好了,到了这里我想大家已经对二叉搜索树有了一定的了解
插入:由于排序二叉树的定义,其思路也是比较简单,只要比当前结点小就去找它的左子树,反之找右子树,为空的话就把当前值设为改根结点的子节点。
删除:删除的话比较复杂,我这边将情况总结为了3种情况,每次都得需要考虑被删结点是不是根节点,这个应该很基本的判断吧。
1.被删结点是没有孩子:这个时候,我们可以直接将该结点删除即可。
2.被删结点有一个孩子:在这里我们需要判断一下被删结点是它的父结点的左孩子还是右孩子,然后将被删结点的不为空的孩子变成被删结点的父结点的子孩子
3.被删结点有两个孩子:这时候我们有2种方法处理:一种是将被删结点的左子树的最右的结点找到,一种是将被删结点的右子树的最左结点找到,我这里是写的是以右子树的最左结点,其实在这里我们可以简单理解一下,本身这个排序二叉树的中序遍历就是一个递增的数据,删除数据之后,无非就是将被删数据的左边或者右边移过去即可,所谓的左子树的最右结点不就是被删结点的左边的数,另外一个情况就是被删结点的右边的数,找到这个关系之后,我觉得写的话就比较简单,我也在下面的源码中打了注释,这里大家可以根据注释来阅读,
具体的代码实现我没有写出来了,有思路写出来应该就问题不大了。
当菜鸟的第6天 2022-04-14,有什么问题希望各位能够及时指出来。
源码如下:
1 package test; 2 3 import javax.swing.text.DefaultEditorKit; 4 5 public class BST{ 6 static class TreeNode { 7 public int val; 8 public TreeNode left; 9 public TreeNode right; 10 public TreeNode(int x) { val = x; } 11 } 12 private TreeNode root; 13 //排序二叉树的插入 14 public void insert(int key){ 15 if(root == null){ 16 root = new TreeNode(key); 17 return ; 18 } 19 TreeNode current = root; 20 TreeNode parent = null; 21 while(true){ 22 if(key < current.val) 23 { 24 parent = current; 25 current = parent.left; 26 if(current == null){ 27 parent.left = new TreeNode(key); 28 return ; 29 } 30 } 31 else if(key > current.val) 32 { 33 parent = current; 34 current = parent.right; 35 if(current == null){ 36 parent.right = new TreeNode(key); 37 return ; 38 } 39 } 40 else { 41 System.out.println("该节点值已经存在"); 42 return ; 43 } 44 } 45 } 46 //判断排序二叉树中是否存在key 47 public int get(int key){ 48 TreeNode current = root; 49 while(current != null && current.val != key){ 50 if(current.val > key){ 51 current = current.right; 52 }else if(current.val < key){ 53 current = current.left; 54 } 55 } 56 return current == null ? 0 : 1; 57 } 58 /* 59 * 排序二叉树的删除: 60 * 三种情况,此处的孩子并不是指叶子节点,也有可能是son tree 61 * 1.被删节点没有孩子:直接将此节点变为null 62 * 2.被删节点有一个孩子:将此节点变为父节点的孩子 63 * 3.被删节点有两个孩子:找到右孩子里面最小的节点,然后将此节点移到要删的节点的位置 64 * */ 65 public boolean del(int key){ 66 TreeNode parent = root; 67 TreeNode current = root; 68 while(current != null && current.val != key) 69 //注意,此处不能通过get来实现查找key值是否在树中,因为需要通过parent节点来实现删除,如果用key,那么parent就无法来完成删除 70 { 71 parent = current; 72 if(current.val > key) 73 current = current.left; 74 else 75 current = current.right; 76 } 77 if(current == null){ 78 return false; 79 } 80 //case1 81 if(current.left == null && current.right == null) 82 { 83 if(current == root){ 84 root = null; 85 } 86 else if(parent.left == current){ 87 parent.left = null; 88 } 89 else parent.right = null; 90 } 91 //case2: 92 else if(current.left == null){ 93 if(current == root){ 94 root = root.right; 95 } 96 else if(parent.left == current){ 97 parent.left = current.right; 98 } 99 else parent.right = current.right; 100 } 101 else if(current.right == null){ 102 if(current == root){ 103 root = root.left; 104 } 105 else if(parent.left == current){ 106 parent.left = current.left; 107 } 108 else parent.right = current.left; 109 } 110 //case3 111 else{ 112 TreeNode Minr = MinrTree(current); 113 if(current == root) 114 { 115 root = Minr; 116 } 117 else if(parent.left == current){ 118 parent.left = Minr; 119 } 120 else parent.right = Minr; 121 } 122 } 123 //此方法来找出右子树的最小节点 124 public TreeNode MinrTree(TreeNode root){ 125 TreeNode rTree = null; 126 TreeNode rTreeParent = null; 127 TreeNode node = root.right; 128 while(node != null){ 129 rTreeParent = rTree; 130 rTree = node; 131 node = node.left; 132 } 133 if(rTree != root.right){ 134 rTreeParent.left = rTree.right; 135 rTree.right = root.right; 136 } 137 return rTree; 138 } 139 }