二叉排序树的非递归插入,非递归查询,寻找最大值,寻找最小值

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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
package 
whut.tree;
//二叉排序树的非递归插入,非递归查询,寻找最大值,寻找最小值
class 
Node {
    
private 
int 
data;
    
private 
Node left;
    
private 
Node right;
    
public 
Node(
int 
data) {
        
this
.data = data;
    
}
    
public 
int 
getData() {
        
return 
data;
    
}
    
public 
Node getLeft() {
        
return 
left;
    
}
    
public 
void 
setLeft(Node left) {
        
this
.left = left;
    
}
    
public 
Node getRight() {
        
return 
right;
    
}
    
public 
void 
setRight(Node right) {
        
this
.right = right;
    
}
    
// 展示节点数据
    
public 
void 
displayNode() {
        
System.out.println(
" " 
+ data + 
" "
);
    
}
}
// 树
public 
class 
BinaryTree {
    
private 
Node root;
// 树根
    
// 非递归方式插入新的节点数据,
    
public 
void 
insert(
int 
data) {
        
Node newNode = 
new 
Node(data);
        
if 
(root == 
null
) {
            
root = newNode;
        
else 
{
            
// 子节点,当前节点
            
Node current = root;
            
// 父节点
            
Node parent;
            
while 
(
true
)
// 寻找插入的位置
            
{
                
parent = current;
                
// 当小于根节点,插入到左边
                
if 
(data < current.getData()) {
                    
current = current.getLeft();
                    
// 跳出循环
                    
if 
(current == 
null
) {
                        
parent.setLeft(newNode);
                        
return
;
                    
}
                
else 
{
                    
current = current.getRight();
                    
if 
(current == 
null
) {
                        
parent.setRight(newNode);
                        
return
;
                    
}
                
}
            
}
        
}
    
}
    
// 非递归方式实现查询
    
public 
Node find(
int 
data) {
        
Node current = root;
        
while 
(current.getData() != data) {
            
if 
(current.getData() < data)
                
current = current.getLeft();
            
else
                
current = current.getRight();
            
// 当一个元素不在一个二叉树中,肯定为null了
            
if 
(current == 
null
)
                
return 
null
;
        
}
        
// 跳出循环说明找到了那个相等的
        
return 
current;
    
}
    
// 找二叉树最小的节点,一直遍历左孩子,直到其左孩子为null
    
public 
Node findMinNode() {
        
Node current;
        
Node parent;
        
//
        
if 
(root == 
null
) {
            
return 
null
;
        
else 
{
            
parent = root;
            
current = parent.getLeft();
            
while 
(current != 
null
) {
                
parent = current;
                
current = current.getLeft();
            
}
            
return 
parent;
        
}
    
}
    
// 找到二叉排序树的最大值,也就是最右边的孩子
    
public 
Node findMaxNode() {
        
Node current;
        
Node parent;
        
//
        
if 
(root == 
null
) {
            
return 
null
;
        
else 
{
            
parent = root;
            
current = parent.getRight();
            
while 
(current != 
null
) {
                
parent = current;
                
current = current.getRight();
            
}
            
return 
parent;
        
}
    
}
    
// 先要找到节点,然后根据要删除节点的位置进行删除
    
// 删除的节点有三种,叶子节点,有一个节点的节点,有两个节点的节点
    
public 
boolean 
delete(
int 
key) {
        
Node current = root;
        
Node parent = root;
        
// 这里主要是为了区分删除的是左孩子还是右孩子
        
boolean 
isLeftChild = 
false
;
        
// 显然,当current.iData == key 时,current就是需要删除的节点
        
// 在循环中利用parent保存了父类节点
        
while 
(current.getData() != key) {
            
parent = current;
            
if 
(key < current.getData()) {
                
isLeftChild = 
true
;
                
current = current.getLeft();
            
else 
{
                
isLeftChild = 
false
;
                
current = current.getRight();
            
}
            
if 
(current == 
null
)
// 找不到key时返回false
                
return 
false
;
        
}
        
// 当节点为叶子节点的时候
        
if 
(current.getLeft() == 
null 
&& current.getRight() == 
null
) {
            
if 
(current == root)
                
root = 
null
;
            
else 
if 
(isLeftChild)
                
parent.setLeft(
null
);
            
else
                
parent.setRight(
null
);
        
}
        
// 当删除的节点为含有一个子节点的节点
        
// 删除的节点只有一个左子节点时
        
// 必须要考虑被删除的节点是左节点还是右节点
        
else 
if 
(current.getRight() == 
null
) {
            
if 
(current == root)
// 要删除的节点为根节点
                
root = current.getLeft();
            
else 
if 
(isLeftChild)
// 要删除的节点是一个左子节点
                
parent.setLeft(current.getLeft());
            
else
                
parent.setRight(current.getLeft());
// 要删除的节点是一个右子节点
        
}
        
// 当删除的节点为含有一个子节点的节点
        
// 删除的节点只有一个右子节点时
        
// 必须要考虑被删除的节点是左节点还是右节点
        
else 
if 
(current.getLeft() == 
null
) {
            
if 
(current == root)
// 要删除的节点为根节点
                
root = current.getRight();
            
else 
if 
(isLeftChild)
// 要删除的节点是一个左子节点
                
parent.setLeft(current.getRight());
            
else
                
parent.setRight(current.getRight());
// 要删除的节点是一个右子节点
        
}
        
// 当要删除的节点是含有两个节点的时候
        
else
         
{
            
//首先要获取被删除节点的后继节点,current
             
Node successor = getSuccessor(current);
             
if
(current == root)
                
root = successor ;
             
//这里已经屏蔽了后继节点是叶子和非叶子节点
             
else 
if
(isLeftChild)
                    
parent.setLeft(successor);
             
else
                    
parent.setRight(successor);
             
successor.setLeft(current.getLeft());
         
}
        
return 
true
;
    
}
    
// 寻找后记节点,主要是当要删除的节点包含了两个子节点的时候
    
// 返回后继节点,后继节点就是比要删除的节点的关键值要大的节点集合中的最小值。
    
//后继节点要么是被删除节点的不包含左子节点的右节点,要么就是包含左子节点的右节点的子节点
    
private 
Node getSuccessor(Node delNode)
    
{
        
// 后继节点的父节点
        
Node successorParent = delNode;
        
// 后继节点
        
Node successor = delNode.getRight();
        
//判断后继节点是否有左孩子
        
Node current = successor.getLeft();
        
while 
(current != 
null
) {
            
successorParent = successor;
            
successor = current;
            
current = current.getLeft();
        
}
        
//当该后继节点是属于包含左子节点的右节点的子节点
        
if 
(successor != delNode.getRight())
        
{
            
successorParent.setLeft(successor.getRight());
            
//连接被删除节点的右孩子
            
successor.setRight(delNode.getRight());
        
}
        
return 
successor;
    
}
    
// 下面三种遍历树
    
// 三种遍历均是采用递归实现的
    
// 前序遍历
    
public 
void 
preOrder(Node localRoot) {
        
if 
(localRoot != 
null
) {
            
localRoot.displayNode();
// 访问这个节点
            
preOrder(localRoot.getLeft());
// 调用自身来遍历左子树
            
preOrder(localRoot.getRight());
// 调用自身来遍历右子树
        
}
    
}
    
// 中序遍历
    
public 
void 
midOrder(Node localRoot) {
        
if 
(localRoot != 
null
) {
            
preOrder(localRoot.getLeft());
// 调用自身来遍历左子树
            
localRoot.displayNode();
// 访问这个节点
            
preOrder(localRoot.getRight());
// 调用自身来遍历右子树
        
}
    
}
    
// 后续遍历
    
public 
void 
lastOrder(Node localRoot) {
        
if 
(localRoot != 
null
) {
            
preOrder(localRoot.getLeft());
// 调用自身来遍历左子树
            
preOrder(localRoot.getRight());
// 调用自身来遍历右子树
            
localRoot.displayNode();
// 访问这个节点
        
}
    
}
}

二叉排序树的递归插入,递归遍历,递归查询

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
package 
whut.tree;
//二叉树的存储,这里会建立一个二叉排序树,递归方式
public 
class 
NodeTree {
    
public 
int 
value;
    
public 
NodeTree left;
    
public 
NodeTree right;
    
//递归实现存储
    
public 
void 
store(
int 
value) {
        
if 
(value < 
this
.value) {
            
if 
(left == 
null
) {
                
left = 
new 
NodeTree();
                
left.value = value;
            
else 
{
                
left.store(value);
            
}
        
else 
if 
(value > 
this
.value) {
            
if 
(right == 
null
)
            
{
                
right = 
new 
NodeTree();
                
right.value = value;
            
else 
{
                
right.store(value);
            
}
        
}
    
}
    
public 
boolean 
find(
int 
value) {
        
System.out.println(
"find happen " 
this
.value);
        
if 
(value == 
this
.value) {
            
return 
true
;
        
else 
if 
(value > 
this
.value) {
            
if 
(right == 
null
)
                
return 
false
;
            
return 
right.find(value);
        
else 
{
            
if 
(left == 
null
)
                
return 
false
;
            
return 
left.find(value);
        
}
    
}
    
//前序遍历
    
public 
void 
preList() {
        
System.out.print(
this
.value + 
","
);
        
if 
(left != 
null
)
            
left.preList();
        
if 
(right != 
null
)
            
right.preList();
    
}
             
    
//中序遍历
    
public 
void 
middleList() {
        
if 
(left != 
null
)
            
left.middleList();
        
System.out.print(
this
.value + 
","
);
        
if 
(right != 
null
)
            
right.middleList();
    
}
     
//后续遍历
    
public 
void 
afterList() {
        
if 
(left != 
null
)
            
left.afterList();
        
if 
(right != 
null
)
            
right.afterList();
        
System.out.print(
this
.value + 
","
);
    
}
    
public 
static 
void 
main(String[] args) {
        
int
[] data = 
new 
int
[
20
];
        
for 
(
int 
i = 
0
; i < data.length; i++) {
            
data[i] = (
int
) (Math.random() * 
100
) + 
1
;
            
System.out.print(data[i] + 
","
);
        
}
        
System.out.println();
        
NodeTree root = 
new 
NodeTree();
        
root.value = data[
0
];
        
for 
(
int 
i = 
1
; i < data.length; i++) {
            
root.store(data[i]);
        
}
        
//查询
        
root.find(data[
19
]);
        
//先序
        
root.preList();
        
System.out.println();
        
//中序
        
root.middleList();
        
System.out.println();
        
//后续
        
root.afterList();
    
}
}