排序算法 Sorting Algorithm(一)

练习下算法规范描述问题和伪代码表示

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++];
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/u013453787/article/details/82529898