Skip to content

Commit 3496a63

Browse files
committed
二叉搜索树
1 parent 1692361 commit 3496a63

7 files changed

Lines changed: 406 additions & 1 deletion

File tree

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
package cn.edu.tju.rico.BinarySearchTree;
2+
3+
public class BinarySearchTree {
4+
5+
private TreeNode root;
6+
7+
/**
8+
* @description 根据已知序列构建二叉搜索树
9+
* @author rico
10+
* @created 2017年6月3日 下午6:15:54
11+
* @param input
12+
*/
13+
public BinarySearchTree(int[] input) {
14+
createBinarySearchTree(input);
15+
}
16+
17+
/**
18+
* @description 根据已知序列构建二叉搜索树
19+
* @author rico
20+
* @created 2017年6月3日 下午6:15:06
21+
* @param input
22+
*/
23+
public void createBinarySearchTree(int[] input) {
24+
if (input != null) {
25+
for (int i = 0; i < input.length; i++) {
26+
root = insert(input[i], root);
27+
}
28+
}
29+
}
30+
31+
/**
32+
* @description 二叉搜索树的搜索算法,递归算法
33+
* @author rico
34+
* @created 2017年6月3日 下午3:27:43
35+
* @param target
36+
* 目标值
37+
* @param root
38+
* 二叉搜索树的根结点
39+
* @return
40+
*/
41+
public TreeNode search(int target, TreeNode root) {
42+
TreeNode result = null;
43+
if (root != null) { // 递归终止条件
44+
if (target == root.data) { // 递归终止条件
45+
result = root;
46+
return result;
47+
} else if (target < root.data) { // 目标值小于根结点值,从左子树查找
48+
result = search(target, root.left);
49+
} else { // 目标值大于根结点值,从右子树查找
50+
result = search(target, root.right);
51+
}
52+
}
53+
return result;
54+
}
55+
56+
/**
57+
* @description 二叉搜索树的插入操作
58+
* @author rico
59+
* @created 2017年6月3日 下午5:55:05
60+
* @param target
61+
* @param node
62+
* @return
63+
*/
64+
public TreeNode insert(int target, TreeNode node) {
65+
if (search(target, node) == null) {
66+
if (node == null) {
67+
return new TreeNode(target);
68+
} else {
69+
if (target < node.data) {
70+
node.left = insert(target, node.left);
71+
} else {
72+
node.right = insert(target, node.right);
73+
}
74+
}
75+
}
76+
return node;
77+
}
78+
79+
/**
80+
* @description 删除搜索二叉树的制定结点
81+
* @author rico
82+
* @created 2017年6月3日 下午8:43:29
83+
* @param target
84+
* @param node
85+
* @return
86+
*/
87+
public TreeNode remove(int target, TreeNode node) {
88+
TreeNode tmp = null;
89+
if (node != null) {
90+
if (target < node.data) { // 从左子树删除
91+
node.left = remove(target, node.left);
92+
} else if (target > node.data) { // 从右子树删除
93+
node.right = remove(target, node.right);
94+
} else if (node.left != null && node.right != null) { // 找到待删除结点,且其左右子树不为空
95+
// 找到以待删除结点右子树的中序遍历第一个结点(最小结点)
96+
tmp = node.right;
97+
while (tmp.left != null) {
98+
tmp = tmp.left;
99+
}
100+
101+
// 用最小结点补位待删除结点
102+
node.data = tmp.data;
103+
104+
// 删除待删除结点右子树上补位结点
105+
node.right = remove(node.data, node.right);
106+
} else {
107+
if (node.left == null) {
108+
node = node.right;
109+
} else {
110+
node = node.left;
111+
}
112+
}
113+
}
114+
return node;
115+
}
116+
117+
/**
118+
* @description 中序遍历二叉搜索树,递归算法,升序排序
119+
* @author rico
120+
* @created 2017年6月3日 下午3:52:54
121+
* @param root
122+
*/
123+
public void inOrder(TreeNode node) {
124+
if (node != null) {
125+
inOrder(node.left);
126+
System.out.print(root.data + " ");
127+
inOrder(node.right);
128+
}
129+
}
130+
131+
/**
132+
* @description 打印二叉搜索树
133+
* @author rico
134+
* @created 2017年6月3日 下午6:08:42
135+
* @param node
136+
*/
137+
public void printTree(TreeNode node) {
138+
if (node != null) {
139+
System.out.print(node.data);
140+
if (node.left != null || node.right != null) {
141+
System.out.print("(");
142+
printTree(node.left);
143+
System.out.print(",");
144+
printTree(node.right);
145+
System.out.print(")");
146+
}
147+
}
148+
}
149+
150+
/**
151+
* @description 访问二叉搜索树的根结点
152+
* @author rico
153+
* @created 2017年6月3日 下午3:54:49
154+
* @return
155+
*/
156+
public TreeNode getRoot() {
157+
return root;
158+
}
159+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
package cn.edu.tju.rico.BinarySearchTree;
3+
4+
public class TreeNode {
5+
6+
public int data;
7+
public TreeNode left;
8+
public TreeNode right;
9+
10+
public TreeNode(int data){
11+
this.data = data;
12+
}
13+
14+
@Override
15+
public String toString() {
16+
return "TreeNode [data=" + data + "]";
17+
}
18+
19+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package cn.edu.tju.rico.backtrack;
2+
3+
import java.util.Arrays;
4+
import java.util.Date;
5+
6+
/**
7+
* Title: 八皇后问题(递归算法) Description: 在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,
8+
* 即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
9+
*
10+
* @author rico
11+
* @created 2017年5月31日 下午4:54:17
12+
*/
13+
public class EightQueen {
14+
15+
private static final short N = 8; // 使用常量来定义,方便之后解N皇后问题
16+
private static int count = 0; // 结果计数器
17+
18+
public static void main(String[] args) {
19+
Date begin = new Date();
20+
// 初始化棋盘,全部置0
21+
short chess[][] = new short[N][N];
22+
for (int i = 0; i < N; i++) {
23+
for (int j = 0; j < N; j++) {
24+
chess[i][j] = 0;
25+
}
26+
}
27+
28+
putQueenAtRow(chess, 0);
29+
Date end = new Date();
30+
System.out.println("解决 " + N + " 皇后问题,用时:"
31+
+ String.valueOf(end.getTime() - begin.getTime()) + "毫秒,计算结果:"
32+
+ count);
33+
}
34+
35+
private static void putQueenAtRow(short[][] chess, int row) {
36+
// 递归终止判断:如果row==N,则说明已经成功摆放了8个皇后 输出结果,终止递归
37+
if (row == N) {
38+
count++;
39+
System.out.println("第 " + count + " 种解:");
40+
for (int i = 0; i < N; i++) {
41+
for (int j = 0; j < N; j++) {
42+
System.out.print(chess[i][j] + " ");
43+
}
44+
System.out.println();
45+
}
46+
return;
47+
}
48+
49+
short[][] chessTemp = chess.clone();
50+
51+
/**
52+
* 向这一行的每一个位置尝试排放皇后 然后检测状态,如果安全则继续执行递归函数摆放下一行皇后
53+
*/
54+
for (int i = 0; i < N; i++) {
55+
// 摆放这一行的皇后,之前要清掉所有这一行摆放的记录,防止污染棋盘
56+
for (int j = 0; j < N; j++)
57+
chessTemp[row][j] = 0;
58+
59+
chessTemp[row][i] = 1;
60+
61+
if (isSafety(chessTemp, row, i)) {
62+
putQueenAtRow(chessTemp, row + 1);
63+
// System.out.println("-----------");
64+
// for (int k = 0; k < N; k++) {
65+
// for (int j = 0; j < N; j++) {
66+
// System.out.print(chess[k][j] + " ");
67+
// }
68+
// System.out.println();
69+
// }
70+
}
71+
}
72+
}
73+
74+
private static boolean isSafety(short[][] chess, int row, int col) {
75+
// 判断中上、左上、右上是否安全
76+
int step = 1;
77+
while (row - step >= 0) {
78+
if (chess[row - step][col] == 1) // 中上
79+
return false;
80+
if (col - step >= 0 && chess[row - step][col - step] == 1) // 左上
81+
return false;
82+
if (col + step < N && chess[row - step][col + step] == 1) // 右上
83+
return false;
84+
85+
step++;
86+
}
87+
return true;
88+
}
89+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package cn.edu.tju.rico.sort;
2+
3+
import java.util.Arrays;
4+
5+
6+
/**
7+
* Title:快速排序的变形
8+
* Description: 本质上不断调用经典快排的划分算法
9+
* 时间复杂度:O(n^2)
10+
* @author rico
11+
* @created 2017年6月2日 下午9:10:43
12+
*/
13+
public class QuickSort_PartitionOnly {
14+
/**
15+
* @description 依次以数组中的每个元素为基准点进行划分,
16+
* 直到遍历所有元素都
17+
* @author rico
18+
* @param array
19+
*/
20+
public void quicksort(int[] array) {
21+
if (array != null && array.length != 0) {
22+
for (int i = 0; i < array.length; i++) {
23+
// 以下是快排的划分算法
24+
int base_index = 0;
25+
int base = array[i];
26+
base_index = i;
27+
for (int j = i+1; j < array.length; j++) {
28+
if (array[j] <= base ) {
29+
base_index ++;
30+
if (base_index != j) {
31+
int temp = array[base_index];
32+
array[base_index] = array[j];
33+
array[j] = temp;
34+
}
35+
}
36+
}
37+
array[i] = array[base_index];
38+
array[base_index] = base;
39+
System.out.println(Arrays.toString(array));
40+
}
41+
}
42+
}
43+
44+
public static void main(String[] args) {
45+
// int[] array = { 1, 2, 3, 2, 2, 2, 5, 4, 2 };
46+
int[] array = { 1, 2, 3, 5, 0, 4, 9, 2, 6 };
47+
new QuickSort_PartitionOnly().quicksort(array);
48+
}
49+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package cn.edu.tju.rico.test;
2+
3+
import cn.edu.tju.rico.BinarySearchTree.BinarySearchTree;
4+
5+
public class BinarySearchTreeTest {
6+
public static void main(String[] args) {
7+
int[] input = {53,78,65,17,87,9,81,45,23};
8+
BinarySearchTree tree = new BinarySearchTree(input);
9+
10+
System.out.println("中序遍历二叉搜索树:");
11+
tree.inOrder(tree.getRoot());
12+
System.out.println();
13+
System.out.println("\n------------------------\n");
14+
System.out.println("打印二叉搜索树:");
15+
tree.printTree(tree.getRoot());
16+
System.out.println();
17+
System.out.println("\n------------------------\n");
18+
19+
System.out.println("二叉搜索树搜索目标值:");
20+
System.out.println(tree.search(23, tree.getRoot()));
21+
System.out.println("\n------------------------\n");
22+
23+
System.out.println("向二叉搜索树插入目标值:");
24+
tree.insert(10, tree.getRoot());
25+
tree.printTree(tree.getRoot());
26+
System.out.println();
27+
System.out.println("\n------------------------\n");
28+
29+
System.out.println("向二叉搜索树删除目标值:");
30+
tree.remove(78, tree.getRoot());
31+
tree.printTree(tree.getRoot());
32+
System.out.println();
33+
System.out.println("\n------------------------\n");
34+
}
35+
}

src/cn/edu/tju/rico/test/SortTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public static void main(String[] args) {
5757

5858
System.out.println("\n----------------------\n");
5959
System.out.println("希尔排序 : ");
60-
int[] target7 = { 21, 25, 49, 25, 16, 8, 31, 41 };
60+
int[] target7 = { 21, 25, 49, 25, 16, 8, 31, 41,1,16 };
6161
System.out.println("原数组 : " + Arrays.toString(target7));
6262
ShellSort.shellSort(target7);
6363
System.out.println(Arrays.toString(target7));

0 commit comments

Comments
 (0)