练习下算法规范描述问题和伪代码表示
Input: sequence 〈a1, a2, …, an〉of numbers.
Output: permutation 〈a’1, a’2, …, a’n〉Such that a’1≤a’2≤…≤a’n.
Example: Input: 8 2 4 9 3 6
Output: 2 3 4 6 8 9
- 插入排序(INSERTION-SORT)
INSERTION-SORT (A, n) ⊳A[1 . . n]
for j←2 to n
do key← A[ j]
i← j–1
while i>0 and A[i] > key
do A[i+1] ← A[i]
i← i –1
A[i+1] = key
稳定性:稳定
时间开销:
与输入规模有关
与输入序列特性有关
最佳情况运行时间: 输入数组已经排好序
最坏情况运行时间: 顺序刚好相反
插入排序的最坏情况时间复杂度 Θ(n^2)
JAVA:
public class InsertSort{
public static void main(String[] args){
int[] A = {1,2,5,4,3,6,9,7,8};
System.out.println(Arrays.toString(A));
insertionSort(A,9);
System.out.println(Arrays.toString(A));
}
public static int[] insertionSort(int[] A, int n) {
int j = 0, temp = 0;
for(j = 0; j < n; j++){
temp = A[j];
for(int i = j - 1; i >= 0; i--){
if(A[i] <= temp) continue;
for(int k = j; k >= i; k--){
A[k+1] = A[k];
}
A[i] = temp;
break;
}
}
return A;
}
}
- 合并排序(Merge Sort)
利用的典型的分治(divide-and-conquer)思想。
1.If n= 1, done.
2.Recursively sort A[ 1 . . .n/2.]and A[ [n/2]+1 . . n ] .
3.“Merge” the 2 sorted lists.
Key subroutine: MERGE
分:递归拆分子序列的过程,递归深度为log2n。
治:将两个已经有序的子序列合并成一个有序序列,其时间复杂度为O(n)
故合并排序的时间复杂度为O(n*logn),且其最好最坏复杂度均为O(n*logn)(过程不变)
merge sort beats insertion sort for n> 30 or so
稳定性:稳定
JAVA
public class MergeSort{
public static void main(String[] args){
int[] A = {1,2,5,4,3,6,9,7,8};
System.out.println(Arrays.toString(A));
mergeSort(A,9);
System.out.println(Arrays.toString(A));
}
public static int[] mergeSort(int[] A, int n){
//在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间
int []temp = new int[A.length];
sort(A,0,A.length-1,temp);
return A;
}
private static void sort(int[] A, int left, int right, int[] temp){
if(left < right){
//分
int mid = (left + right)/2;
sort(A, left, mid, temp);
sort(A, mid+1, right, temp);
//治
merge(A, left, mid, right, temp);
}
}
private static void merge(int[] A, int left, int mid, int right, int temp){
int i = left;
int j = mid + 1;
int t = 0;
while(i<=mid && j<=right){
if(A[i]>=A[j]){
temp[t++] = A[j++];
}
else{
temp[t++] = A[i++];
}
while(i<=mid){
temp[t++] = A[i++];
}
while(j<=right){
temp[t++] = A[j++];
}
//将temp中的元素全部拷贝到原数组中
t = 0;
while(left <= right){
A[left++] = temp[t++];
}
}
}
}