Skip to content

Commit 1692361

Browse files
committed
新增折半插入排序和堆排序
1 parent cb9b6ad commit 1692361

6 files changed

Lines changed: 134 additions & 9 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package cn.edu.tju.rico.sort;
2+
3+
4+
/**
5+
* Title: 插入排序中的折半插入排序,依赖于初始序列
6+
* Description: 折半搜索出插入位置,并直接插入;与直接插入搜索的区别是,后者的搜索要快于顺序搜索
7+
* 时间复杂度:折半插入排序比直接插入排序明显减少了关键字之间的比较次数,但是移动次数是没有改变。所以,
8+
* 折半插入排序和插入排序的时间复杂度相同都是O(N^2),在减少了比较次数方面它确实相当优秀,所以该算法仍然比直接插入排序好。
9+
* 空间复杂度:O(1)
10+
* 稳 定 性:稳定
11+
* 内部排序(在排序过程中数据元素完全在内存)
12+
* @author rico
13+
* @created 2017年5月25日 下午12:03:23
14+
*/
15+
public class BinaryInsertSort {
16+
public static int[] binaryInsertSort(int[] target) {
17+
if (target != null && target.length > 1) {
18+
for (int i = 1; i < target.length; i++) {
19+
int left = 0;
20+
int right = i - 1;
21+
int mid;
22+
int temp = target[i];
23+
if(temp < target[right]){ // 当前值小于有序序列的最大值时,开始查找插入位置
24+
while(left <= right){
25+
mid = (left + right)/2;
26+
if(target[mid] < temp){
27+
left = mid + 1; // 缩小插入区间
28+
}else if(target[mid] > temp){
29+
right = mid - 1; // 缩小插入区间
30+
}else{ // 待插入值与有序序列中的target[mid]相等,保证稳定性的处理
31+
left = left + 1;
32+
}
33+
}
34+
35+
// left及其后面的数据顺序向后移动,并在left位置插入
36+
for (int j = i; j > left; j--) {
37+
target[j] = target[j-1];
38+
}
39+
target[left] = temp;
40+
}
41+
}
42+
}
43+
return target;
44+
}
45+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package cn.edu.tju.rico.sort;
2+
3+
/**
4+
* Title: 堆排序(选择排序),升序排序(最大堆)
5+
* Description: 现将给定序列调整为最大堆,然后每次将堆顶元素与堆尾元素交换并缩小堆的范围,直到将堆缩小至1
6+
* 时间复杂度:O(nlgn)
7+
* 空间复杂度:O(1)
8+
* 稳 定 性:不稳定
9+
* 内部排序(在排序过程中数据元素完全在内存)
10+
* @author rico
11+
* @created 2017年5月25日 上午9:48:06
12+
*/
13+
public class HeapSort {
14+
15+
public static int[] heapSort(int[] target) {
16+
if (target != null && target.length > 1) {
17+
18+
// 调整为最大堆
19+
int pos = (target.length - 2) / 2;
20+
while (pos >= 0) {
21+
shiftDown(target, pos, target.length - 1);
22+
pos--;
23+
}
24+
25+
// 堆排序
26+
for (int i = target.length-1; i > 0; i--) {
27+
int temp = target[i];
28+
target[i] = target[0];
29+
target[0] = temp;
30+
shiftDown(target, 0, i-1);
31+
}
32+
return target;
33+
}
34+
return target;
35+
}
36+
37+
38+
/**
39+
* @description 自上而下调整为最大堆
40+
* @author rico
41+
* @created 2017年5月25日 上午9:45:40
42+
* @param target
43+
* @param start
44+
* @param end
45+
*/
46+
private static void shiftDown(int[] target, int start, int end) {
47+
int i = start;
48+
int j = 2 * start + 1;
49+
int temp = target[i];
50+
while (j <= end) { // 迭代条件
51+
if (j < end && target[j + 1] > target[j]) { //找出较大子女
52+
j = j + 1;
53+
}
54+
if (target[j] <= temp) { // 父亲大于子女
55+
break;
56+
} else {
57+
target[i] = target[j];
58+
i = j;
59+
j = 2 * j + 1;
60+
}
61+
}
62+
target[i] = temp;
63+
}
64+
}

src/cn/edu/tju/rico/sort/QuickSort.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44

55
/**
66
* Title: 交换排序中的快速排序,目前应用最为广泛的排序算法,是一个递归算法
7-
* Description:归并排序包括两个过程:划分 和 快排
7+
* Description:快速排序包括两个过程:划分 和 快排
88
* "划分"是指将原序列按基准元素划分两个子序列
99
* "快排"是指分别对子序列进行快排
1010
*
1111
* 就平均计算时间而言,快速排序是所有内部排序方法中最好的一个
1212
*
1313
* 对大规模数据排序时,快排是快的;对小规模数据排序时,快排是慢的,甚至慢于简单选择排序等简单排序方法
1414
*
15-
* 归并排序依赖于原始序列,因此其时间复杂度从O(nlgn)到O(n^2)不等
15+
* 快速排序依赖于原始序列,因此其时间复杂度从O(nlgn)到O(n^2)不等
1616
* 时间复杂度:最好情形O(nlgn),平均情形O(nlgn),最差情形O(n^2)
1717
*
1818
* 递归所消耗的栈空间

src/cn/edu/tju/rico/sort/RadixSort.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public static int[] radixSort(int[] target, int r, int d, int n){
5252
}
5353
count[j] = 0; // 计数器归零
5454
}
55-
divisor *= 10; //用于获取元素对应位数字
55+
divisor *= 10; //用于获取元素对应位数字
5656
}
5757
}
5858
return target;

src/cn/edu/tju/rico/sort/StraightInsertionSort.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package cn.edu.tju.rico.sort;
22

33
/**
4-
* Title: 插入排序中的直接插入排序
4+
* Title: 插入排序中的直接插入排序 ,依赖于初始序列
55
* Description: 在有序序列中不断插入新的记录以达到扩大有序区到整个数组的目的
66
* 时间复杂度:最好情形O(n),平均情形O(n^2),最差情形O(n^2)
77
* 空间复杂度:O(1)
@@ -14,10 +14,10 @@ public class StraightInsertionSort {
1414

1515
public static int[] insertSort(int[] target){
1616

17-
if(target != null && target.length != 1){
18-
for (int i = 1; i < target.length; i++) {
19-
for (int j = i; j > 0; j--) {
20-
if(target[j] < target[j-1]){
17+
if(target != null && target.length != 1){ // 待排序数组不为空且长度大于1
18+
for (int i = 1; i < target.length; i++) { // 不断扩大有序序列,直到扩展到整个数组
19+
for (int j = i; j > 0; j--) { // 向有序序列中插入新的元素
20+
if(target[j] < target[j-1]){ // 交换
2121
int temp = target[j];
2222
target[j] = target[j-1];
2323
target[j-1] = temp;
@@ -27,4 +27,4 @@ public static int[] insertSort(int[] target){
2727
}
2828
return target;
2929
}
30-
}
30+
}

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import java.util.Arrays;
44

5+
import cn.edu.tju.rico.sort.BinaryInsertSort;
56
import cn.edu.tju.rico.sort.BubbleSort;
7+
import cn.edu.tju.rico.sort.HeapSort;
68
import cn.edu.tju.rico.sort.MergeSort;
79
import cn.edu.tju.rico.sort.QuickSort;
810
import cn.edu.tju.rico.sort.RadixSort;
@@ -73,5 +75,19 @@ public static void main(String[] args) {
7375
System.out.println("原数组 : " + Arrays.toString(target9));
7476
RadixSort.radixSort(target9,10,2,target9.length);
7577
System.out.println(Arrays.toString(target9));
78+
79+
System.out.println("\n----------------------\n");
80+
System.out.println("堆排序 : ");
81+
int[] target10 = { 21, 25, 49, 25, 16, 18, 31, 41 };
82+
System.out.println("原数组 : " + Arrays.toString(target10));
83+
HeapSort.heapSort(target10);
84+
System.out.println(Arrays.toString(target10));
85+
86+
System.out.println("\n----------------------\n");
87+
System.out.println("折半插入排序 : ");
88+
int[] target11 = { 21, 25, 49, 25, 16, 18, 31, 41, 21, 9 };
89+
System.out.println("原数组 : " + Arrays.toString(target11));
90+
BinaryInsertSort.binaryInsertSort(target11);
91+
System.out.println(Arrays.toString(target11));
7692
}
7793
}

0 commit comments

Comments
 (0)