Skip to content

Commit 1f23f50

Browse files
committed
树相关内容2
1 parent bbf0a45 commit 1f23f50

File tree

9 files changed

+455
-26
lines changed

9 files changed

+455
-26
lines changed
Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,11 @@
11
package zhaoyu.DataStructures.Trees;
22

33
/**
4-
* @Description: 平衡二叉树,也称为AVL
4+
* @Description: AVL是一种平衡二叉搜索树。旋转(rotate)不会破会二叉搜索树的特性,AVL就是通过旋转保证AVL的平衡。
55
* @Author: zhaoyu
66
* @Date: 2021/1/26
77
*/
8-
public class AVLTree {
8+
public class AVLTree <E>{
99

10-
class Node{
11-
private int key;
12-
private Node left;
13-
private Node right;
14-
private Node parent;
1510

16-
public Node(int key,Node p) {
17-
this.key=key;
18-
this.parent=p;
19-
}
20-
}
21-
22-
private Node root;
23-
24-
public void insert(int key){
25-
26-
}
2711
}
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
package zhaoyu.DataStructures.Trees;
2+
3+
/**
4+
* 二叉搜索树
5+
* 在一个有序队列中,二分法查找扩展到所有元素,就会形成一个二叉搜索树。参考binary-search-tree.png。
6+
* @param <E>
7+
*/
8+
public class BinarySearchTree<E extends Comparable<E>> extends BinaryTree<E>{
9+
protected Node<E> searchValue(E value,Node<E> root){
10+
if (root == null) {
11+
return null;
12+
}
13+
int comp = root.getValue().compareTo(value);
14+
if (comp == 0) {
15+
return root;
16+
} else if (comp > 0) {
17+
return searchValue(value, root.getLeft());
18+
} else {
19+
return searchValue(value, root.getRight());
20+
}
21+
}
22+
23+
/**
24+
* 查找值,不存在,返回null。
25+
* @param value
26+
* @return zhaoyu.DataStructures.Trees.BinaryTree.Node<E>
27+
*/
28+
public Node<E> searchValue(E value){
29+
if (getRoot() == null) {
30+
return null;
31+
} else {
32+
return searchValue(value, getRoot());
33+
}
34+
}
35+
36+
/**
37+
* 插入一个元素,分为两步,首先找到插入的位置,插入的值大于当前节点,向右查找,插入的值小于当前节点,向左查找。直到找到空位置。
38+
* 第二部简单地插入元素。
39+
* 参考binary-search-tree-insert.png
40+
* @param value
41+
* @param node
42+
* @return
43+
*/
44+
protected Node<E> insertValue(E value,Node<E> node){
45+
int comp = value.compareTo(node.getValue());
46+
Node<E> child;
47+
if (comp <= 0) {
48+
child = node.getLeft();
49+
if (null == child) {
50+
return addChild(node, value, true);
51+
} else {
52+
return insertValue(value, child);
53+
}
54+
} else if (comp > 0) {
55+
child = node.getRight();
56+
if (null == child) {
57+
return addChild(node, value, false);
58+
} else {
59+
return insertValue(value, child);
60+
}
61+
} else {
62+
return null;
63+
}
64+
}
65+
66+
public Node<E> insertValue(E value){
67+
if (getRoot() == null) {
68+
addRoot(value);
69+
return getRoot();
70+
} else {
71+
return insertValue(value, getRoot());
72+
}
73+
}
74+
75+
/**
76+
* 删除没有子节点的节点。
77+
* @param node
78+
* @return void
79+
*/
80+
public void deleteNodeWithSubtree(Node<E> node){
81+
if (node == null) {
82+
throw new NullPointerException("父节点为空,不能删除");
83+
} else if (node.containerTree != this) {
84+
throw new IllegalArgumentException("节点不属于当前树");
85+
} else {
86+
if (node == getRoot()) {
87+
root = null;
88+
return;
89+
} else {
90+
Node<E> parent=node.getParent();
91+
if (parent.getLeft() == node) {
92+
parent.left = null;
93+
} else {
94+
parent.right= null;
95+
}
96+
}
97+
}
98+
99+
}
100+
101+
/**
102+
* 从树种删除任意节点。
103+
* @param delNode
104+
* @return zhaoyu.DataStructures.Trees.BinaryTree.Node<E>
105+
*/
106+
private Node<E> deleteNode(Node<E> delNode){
107+
boolean left;
108+
if (delNode.getParent() != null && delNode.getParent().getLeft() == delNode) {
109+
left = true;
110+
} else {
111+
left=false;
112+
}
113+
114+
//1,节点没有子节点,直接删除。
115+
if (delNode.getLeft() == null && delNode.getRight() == null) {
116+
deleteNodeWithSubtree(delNode);
117+
return delNode;
118+
}
119+
//2,只有右子树
120+
else if (delNode.getLeft()==null) {
121+
//如果删除的是根节点
122+
if (delNode.getParent() == null) {
123+
root = delNode.getRight();
124+
} else {
125+
setChild(delNode.getParent(), delNode.getRight(), left);
126+
}
127+
return delNode;
128+
}
129+
//3,只有左子树
130+
else if (delNode.getRight() == null) {
131+
//如果删除的是根节点
132+
if (delNode.getParent() == null) {
133+
root = delNode.getLeft();
134+
} else {
135+
setChild(delNode.getParent(), delNode.getLeft(), left);
136+
}
137+
return delNode;
138+
}
139+
//4,同时有左右子树。使用右子树的最小值替换删除节点,并删除右子树最小值,右子树最小值是叶节点,所以可以直接删除。
140+
else {
141+
//找到右子树最小节点。
142+
Node<E> nodeToBeReplaced = getLeftMost(delNode.getRight());
143+
//替换删除节点
144+
setValue(delNode, nodeToBeReplaced.getValue());
145+
//直接删除右子树最小值。
146+
deleteNode(nodeToBeReplaced);
147+
return nodeToBeReplaced;
148+
}
149+
}
150+
151+
/**
152+
* 查找一个子树的最小节点并返回。
153+
* @param node
154+
* @return zhaoyu.DataStructures.Trees.BinaryTree.Node<E>
155+
*/
156+
protected Node<E> getLeftMost(Node<E> node){
157+
if (node == null) {
158+
return null;
159+
} else if (node.getLeft() == null) {
160+
return node;
161+
} else {
162+
return getLeftMost(node.getLeft());
163+
}
164+
}
165+
166+
/**
167+
* 向树种插入20个随机数,并打印。打印后你会发现,中序遍历的二叉搜索树是按顺序排列好的
168+
* @param
169+
* @return void
170+
*/
171+
public static void insert1to20() {
172+
BinarySearchTree<Integer> tree = new BinarySearchTree<>();
173+
for (int i = 0; i < 20; i++) {
174+
int value= (int) (100*Math.random());
175+
tree.insertValue(value);
176+
}
177+
tree.traverseDepthFirst(x-> System.out.print(x+","),tree.getRoot(),DepthFirstTraversalType.INORDER);
178+
System.out.println();
179+
}
180+
181+
public static void main(String[] args) {
182+
insert1to20();
183+
}
184+
}

0 commit comments

Comments
 (0)