Skip to content

Commit 769ffdd

Browse files
committed
添加二叉搜索树,以及树的先序,中序,后序递归和非递归实现
1 parent b26e8b4 commit 769ffdd

File tree

2 files changed

+311
-0
lines changed

2 files changed

+311
-0
lines changed
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
package cn.byhieg.algorithmtutorial;
2+
3+
/**
4+
* Created by byhieg on 17/3/30.
5+
* Mail to byhieg@gmail.com
6+
*/
7+
8+
import java.util.Stack;
9+
10+
/**
11+
* 该类是二叉搜索树
12+
* 该树在实现的时候,不考虑数组中有重复的数字。
13+
* 节点的左子节点的值都小于这个节点的值,节点的右子节点的值都大于等于这个节点的值
14+
*/
15+
public class BinarySearchTree {
16+
17+
private Node root;
18+
19+
20+
public BinarySearchTree(){
21+
22+
}
23+
24+
25+
public BinarySearchTree(int[] nums) {
26+
Node[] nodes = new Node[nums.length];
27+
for (int i = 0 ; i < nums.length;i++) {
28+
nodes[i] = new Node(nums[i]);
29+
insert(nodes[i]);
30+
}
31+
}
32+
33+
/**
34+
* 查找指定的元素
35+
* @param des
36+
* @return
37+
*/
38+
public Node find(int des){
39+
if (root == null) {
40+
System.out.println("树是空的");
41+
throw new RuntimeException();
42+
}
43+
Node current = root;
44+
while (current.data != des) {
45+
if (current.data < des) {
46+
current = current.right;
47+
}else{
48+
current = current.left;
49+
}
50+
if (current == null) return null;
51+
}
52+
return current;
53+
}
54+
55+
/**
56+
* 对BST执行插入操作,采用非递归的形式
57+
* 保证插入后,左节点的值小于根节点的值,根节点的值小于右节点的值
58+
* @param node
59+
* @return
60+
*/
61+
public boolean insert(Node node){
62+
if (root == null) {
63+
root = node;
64+
return true;
65+
}
66+
67+
if (find(node.data) != null) {
68+
System.out.println("不允许插入相同data的数");
69+
throw new RuntimeException();
70+
}
71+
72+
Node current = root;
73+
while (current != null) {
74+
if (current.data < node.data) {
75+
if (current.right == null) {
76+
current.right = node;
77+
return true;
78+
}
79+
current = current.right;
80+
}else{
81+
if (current.left == null) {
82+
current.left = node;
83+
return true;
84+
}
85+
current = current.left;
86+
}
87+
}
88+
return false;
89+
90+
}
91+
92+
/**
93+
* 树的前序遍历,递归实现
94+
*/
95+
public void preOrder(Node node) {
96+
System.out.print(node.data + "-->");
97+
if (node.left != null) {
98+
preOrder(node.left);
99+
}
100+
if (node.right != null) {
101+
preOrder(node.right);
102+
}
103+
}
104+
105+
/**
106+
* 树的中序遍历,递归实现
107+
* 针对BST,该结果会从小到大输出树
108+
* @param node
109+
*/
110+
public void inOrder(Node node){
111+
if (node.left != null) {
112+
inOrder(node.left);
113+
}
114+
System.out.print(node.data + "-->");
115+
if (node.right != null) {
116+
inOrder(node.right);
117+
}
118+
}
119+
120+
/**
121+
* 树的后续遍历,递归实现
122+
*/
123+
public void postOrder(Node node){
124+
if (node.left != null) {
125+
postOrder(node.left);
126+
}
127+
if (node.right != null) {
128+
postOrder(node.right);
129+
}
130+
System.out.print(node.data + "-->");
131+
}
132+
133+
134+
/**
135+
* 树的先续遍历,非递归实现
136+
* 1. 建立一个栈,现将头结点压入栈中。
137+
* 2. 现将每出栈一个节点,打印他的值,然后都要先加入他的右节点,在加入他的左节点。因为栈的后进先出的特性,才能让左边先出。
138+
* 3. 不断重复2,直到栈空
139+
*
140+
*/
141+
public void preOrder2(Node node) {
142+
if (node != null) {
143+
Stack<Node> stack = new Stack<>();
144+
stack.push(node);
145+
while (!stack.isEmpty()) {
146+
Node tmp = stack.pop();
147+
System.out.print(tmp.data + "-->");
148+
if (tmp.right != null) {
149+
stack.push(tmp.right);
150+
}
151+
if (tmp.left != null) {
152+
stack.push(tmp.left);
153+
}
154+
}
155+
}
156+
}
157+
158+
/**
159+
* 树的中序遍历,非递归实现
160+
* 1. 设定cur,初始化cur = root节点,不断遍历里cur.left,并将其压入栈中,直到null。
161+
* 2. 出栈一个节点,打印他的值,然后cur = node.right,并不断重复第二步
162+
* 3. 当栈为空,并且cur为空时,停止
163+
*/
164+
public void inorder2(Node node){
165+
if (node != null) {
166+
Stack<Node> stack = new Stack<>();
167+
Node cur = node;
168+
while (!stack.isEmpty() || cur != null) {
169+
if (cur == null) {
170+
cur = stack.pop();
171+
System.out.print(cur.data + "-->");
172+
cur = cur.right;
173+
}else{
174+
stack.push(cur);
175+
cur = cur.left;
176+
}
177+
}
178+
}
179+
}
180+
181+
/**
182+
* 树的后续遍历,非递归实现
183+
* 1. 树的先续遍历中,是栈存放顺序是根,右节点,左节点。
184+
* 2. 我们可以将其反过来,用栈存放是根,左节点,右节点。然后出栈的时候,将出栈的结果存放到另一个栈里。
185+
* 3. 第二栈里的顺序从上到下就是左节点,右节点,根的顺序。
186+
* @param node
187+
*/
188+
189+
public void postOrder2(Node node) {
190+
if (node != null) {
191+
Stack<Node> stack = new Stack<>();
192+
Stack<Node> result = new Stack<>();
193+
Node cur = node;
194+
stack.push(cur);
195+
while (!stack.isEmpty()){
196+
Node tmp = stack.pop();
197+
result.push(tmp);
198+
if (tmp.left != null) {
199+
stack.push(tmp.left);
200+
}
201+
if (tmp.right != null) {
202+
stack.push(tmp.right);
203+
}
204+
}
205+
206+
while (!result.isEmpty()) {
207+
System.out.print(result.pop().data + "-->");
208+
}
209+
}
210+
}
211+
212+
213+
/**
214+
* 得到树中最小的节点
215+
* @return
216+
*/
217+
public Node getMinNode(){
218+
if (root == null) {
219+
throw new RuntimeException("树为空");
220+
}
221+
Node current = root;
222+
while (current.left != null) {
223+
current = current.left;
224+
}
225+
return current;
226+
227+
}
228+
229+
/**
230+
* 得到树中最大的节点
231+
* @return
232+
*/
233+
public Node getMaxNode(){
234+
if (root == null) {
235+
throw new RuntimeException("树为空");
236+
}
237+
Node current = root;
238+
while (current.right != null) {
239+
current = current.right;
240+
}
241+
242+
return current;
243+
}
244+
245+
public static class Node{
246+
public int data;
247+
public Node left;
248+
public Node right;
249+
250+
public Node(int data){
251+
this.data = data;
252+
}
253+
}
254+
255+
public Node getRoot() {
256+
return root;
257+
}
258+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package cn.byhieg.collectiontutorialtest;
2+
3+
import cn.byhieg.algorithmtutorial.BinarySearchTree;
4+
import com.sun.tools.internal.ws.wsdl.document.soap.SOAPUse;
5+
import junit.framework.TestCase;
6+
import org.junit.Assert;
7+
8+
/**
9+
* Created by byhieg on 17/3/30.
10+
* Mail to byhieg@gmail.com
11+
*/
12+
public class BinarySearchTreeTest extends TestCase {
13+
int [] nums;
14+
BinarySearchTree tree;
15+
public void setUp() throws Exception {
16+
super.setUp();
17+
nums = new int[]{10,6,2,8,7,3,4,1};
18+
tree = new BinarySearchTree(nums);
19+
}
20+
21+
public void tearDown() throws Exception {
22+
}
23+
24+
25+
public void testInsert() throws Exception {
26+
}
27+
28+
public void testInOrder() throws Exception {
29+
System.out.println("中序遍历");
30+
tree.inorder2(tree.getRoot());
31+
System.out.println();
32+
}
33+
34+
public void testPreOrder() throws Exception {
35+
System.out.println("先续遍历");
36+
tree.preOrder2(tree.getRoot());
37+
System.out.println();
38+
}
39+
40+
public void testPostOrder() throws Exception {
41+
System.out.println("后续遍历");
42+
tree.postOrder2(tree.getRoot());
43+
System.out.println();
44+
}
45+
46+
public void testGetMaxData() throws Exception {
47+
// Assert.assertEquals(12,tree.getMaxNode().data);
48+
}
49+
50+
public void testGetMinData() throws Exception {
51+
// Assert.assertEquals(1,tree.getMinNode().data);
52+
}
53+
}

0 commit comments

Comments
 (0)