- 插入排序
思想:假设前i个数据已排序,将第i+1个数据插入到前面已排序的数据中,那么现在前i+1个数据都已排序,具体过程看伪代码
伪代码:
INSERTION-SORT(A)
for j = 2 to A.length
key = A[j]
i=j-1
// insert A[j] into storted sequence A[1...j-1]
while i > 0 and A[i] > key
A[i+1] == A[i]
i = i - 1
A[i+1] = key
效率:
时间级:
θ(n^2)。
2. 并归排序
使用了递归思想
伪代码:
MERGE-SORT(A, p, r)
if p < r
q = [(p+r)/2]
MERGE-SORT(A, p, q)
MERGE-SORT(A, q+1, r)
MERGE(A, p, q, r)
MERGE(A, p, q, r)
n1 = q - p +1
n2 = r - q
let L[1..n1+1] and R[1..n2+1] be new arrays
for i = 1 to n1
L[i] = A[p + i -1]
for j = 1 to n2
R[j] = A[q + j]
L[n1 + 1] = ∞ //设置哨兵
R[n2 + 1] = ∞ //设置哨兵
i = 1
j = 1
for k = p to r
if L[i] <= R[j]
A[k] = L[i]
i = i + 1
else
A[k] = R[j]
j = j + 1
效率:
时间级:θ(n*log2(n) )
3. 算法实现
实现代码:
/**
* SortUtil.java
* 2014年10月7日 created by kalvenmeng
* mail: kalvenmeng@163.com
* TODO
*/
package com.mfy.tools;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
public class SortUtil {
/**
* <p>
* 插入排序算法
* </p>
* @param array input args
*/
public static void sortByInsertion(int[] array) {
int temp = 0;
for (int j = 1; j < array.length; j++) {
temp = array[j];
int i = j - 1;
while (i >= 0 && array[i] > temp) {
array[i +1 ] = array[ i];
i--;
}
array[i+1] = temp;
}
}
public static void mergeSort(int[] array, int p, int r ) {
if (p < r) {
int q = (p + r)/2;
mergeSort(array, p, q);
mergeSort(array, q + 1, r);
merge(array, p, q, r);
}
}
private static void merge(int[] array, int p, int q, int r) {
int n1 = q - p + 1;
int n2 = r - q;
int[] left = new int[n1 + 1];
int[] right = new int[n2 + 1];
for (int i=0; i < n1; i++) {
left[i] = array[p + i];
}
for (int j = 0; j < n2; j++) {
right[j] = array[q+j+1];
}
left[n1] = Integer.MAX_VALUE;
right[n2] = Integer.MAX_VALUE;
int i = 0;
int j = 0;
for (int k = p; k <= r; k++) {
if (left[i] <= right[j]) {
array[k] = left[i];
i++;
} else {
array[k] = right[j];
j++;
}
}
}
public static void main(String[] args) {
int[] array = getIntArray(new Long(10), 100000);
// int[] array = new int[]{7,6,5,4,3,2,1};
// int[] array = getIntArray(new Long(10), 10);
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
/*for (int i:array) {
System.out.print(i + ",");
}
System.out.println();*/
System.out.println(sf.format(new Date()));
sortByInsertion(array);
// mergeSort(array, 0, array.length-1);
System.out.println(sf.format(new Date()));
/*for (int i:array) {
System.out.print(i + ",");
}*/
}
private static int[] getIntArray (Long seed,int length) {
int[] array = new int[length];
Random random = seed != null ? new Random(seed) : new Random();
for (int i = 0; i < length; i++) {
array[i] = random.nextInt();
}
return array;
}
}
4. 说明
在对100000个int数组排序上 插入排序用时7s左右,并归排序用时1s不到
在对900000个int数组排序上 插入排序用时12min左右 ,并归排序用时1s不到
所以随着输入项的增多插入排序在用时上会越来越多,而并归排序并没有这种情况
并归排序在时间效率上远远高于插入排序,
更多详细内容请参阅《算法与导论(原书第三版)》第二章,算法基础