本文最后更新于:July 27, 2024 8:58 PM
这是在看b站上的韩顺平老师的数据结构与算法时做的笔记。等我把后面的都更新完了以后会陆续把前面的补上。
一、实际案例
给你一个数列(7,3,10,12,5,1,9)要求能够高效地完成对数组的查找与添加
二、解决方案
- 使用数组|ArrayList
- 数组未排序时:
- 数组排序时:
- 优点:用二分查找时,查找速度快
- 缺点 :为了保证数组有序,添加新数据时速度慢
- 链式存储-链表|LinkedList
- 优点:添加数据速度比数组快,因为不需要整体移动
- 缺点:查找速度慢
- 二叉排序树|BST
三、基本介绍
一个很好用的BST的可视化网站
二叉排序树:BST(Binary Sort(Search) Tree), 对于它的任何一个非叶子结点|leaf node,要求左子结点的值比当前结点的值小,有子结点的值比当前结点的值大。
特别说明:如有相同的值,可以将该结点放在左子结点或右子结点(最好避免相同的值)
四、构建BST
针对前面的数据(7,3,10,12,5,1,9),对应的二叉排序树为:
![](https://gitee.com/Trotyl15/blogImage/raw/master/img/note/d&a/BST.png)
当插入结点“2”时,“2”应该放在“1”的右子结点
五、删除结点的思路
第一种情况
——删除叶子结点(如:1,5,9,12)
1) 定位结点 targetNode
2)找到targetNode的父结点 parent
3)确定targetNode是parent的左子结点还是右子结点
4)根据前面的情况对应删除
左子结点:parent.left = null
;
右子结点:parent.right = =null
;
第二种情况
——删除只有一颗子树的结点(如:3)
1) 定位结点 targetNode
2)找到targetNode的父结点 parent
3)确定targetNode的子结点是左结点还是右子结点
- 如果targetNode有左子结点
- targetNode是parent的左子结点
parent.left = targetNode.left ;
- targetNode是parent的右子结点
parent.right = targetNode.left ;
- 如果targetNode有右子结点
- targetNode是parent的左子结点
parent.left = targetNode.right ;
- targetNode是parent的右子结点
parent.right = targetNode.right ;
第三种情况
——删除有两颗子树的结点(如:7,3,10)
- 这里用“10”举例,并且假设“12”下面还有两个子结点
1) 定位结点 targetNode
2)找到targetNode的父结点 parent
3)从targetNode的右子树找到最小的结点
4)用一个临时变量,将右子树最小的结点值保存 temp = 11
5)删除该最小结点
6)targetNode.value = temp;
容我说一句:妙啊!
六、代码实现
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
| public class BinarySortTreeDemo { public static void main(String[] args) { int[] arr = { 7, 3, 10, 12, 5, 1, 9, 2 }; BinarySortTree binarySortTree = new BinarySortTree(); for (int i = 0; i < arr.length; i++) { binarySortTree.add(new Node(arr[i])); } binarySortTree.infixOrder(); binarySortTree.delNode(2); binarySortTree.delNode(5); binarySortTree.delNode(9); binarySortTree.delNode(12); binarySortTree.delNode(7); binarySortTree.delNode(3); binarySortTree.delNode(10); System.out.println("After:"); binarySortTree.infixOrder(); } }
class BinarySortTree { private Node root;
public Node search(int value) { if (root == null) { return null; } else { return root.search(value); } }
public Node searchParent(int value) { if (root == null) { return null; } else { return root.searchParent(value); } }
public int delRightTreeMin(Node node) { Node target = node; while (target.left != null) { target = target.left; }
delNode(target.value); return target.value; }
public void delNode(int value) { if (root == null) { return; } else { Node targetNode = search(value); if (targetNode == null) { return; } if (root.left == null && root.right == null) { root = null; return; } Node parent = searchParent(value); if (targetNode.left == null && targetNode.right == null) { if (parent.left != null && parent.left.value == value) { parent.left = null; } else if (parent.right != null && parent.right.value == value) { parent.right = null; } } else if (targetNode.left != null && targetNode.right != null) { int minVal = delRightTreeMin(targetNode.right); targetNode.value = minVal; } else { if (targetNode.left != null) { if (parent != null) { if (parent.left.value == value) { parent.left = targetNode.left; } else { parent.right = targetNode.left; } } else { root = targetNode.left; } } else { if (parent != null) { if (parent.left.value == value) { parent.left = targetNode.right; } else { parent.right = targetNode.right; } } else { root = targetNode.right; } } } } }
public void add(Node node) { if (root == null) { root = node; } else { root.add(node); } }
public void infixOrder() { if (root != null) { root.infixOrder(); } else { System.out.println("Tree is Empty."); } } }
class Node { int value; Node left; Node right;
public Node(int value) { this.value = value; }
public Node search(int value) { if (value == this.value) { return this; } else if (value < this.value) { if (this.left == null) { return null; } return this.left.search(value); } else { if (this.right == null) { return null; } return this.right.search(value); } }
public Node searchParent(int value) { if ((this.left != null && this.left.value == value) || (this.right != null && this.right.value == value)) { return this; } else { if (value < this.value && this.left != null) { return this.left.searchParent(value); } else if (value >= this.value && this.right != null) { return this.right.searchParent(value); } else { return null; } }
}
@Override public String toString() { return "Node [value=" + value + "]"; }
public void add(Node node) { if (node == null) { return; } if (node.value < this.value) { if (this.left == null) { this.left = node; } else { this.left.add(node); } } else { if (this.right == null) { this.right = node; } else { this.right.add(node); } } }
public void infixOrder() { if (this.left != null) { this.left.infixOrder(); } System.out.println(this); if (this.right != null) { this.right.infixOrder(); } } }
|
运行结果
1 2 3 4 5 6 7 8 9 10
| Node [value=1] Node [value=2] Node [value=3] Node [value=5] Node [value=7] Node [value=9] Node [value=10] Node [value=12] After: Node [value=1]
|
参考