经典排序算法

时间:2021-04-13 22:06:34

1.O(n^2)排序算法

1.冒泡排序

int* bubbleSort1(int* A, int n) {
        int k=0;//last sink position
        for(int i=n-1;i>0;i=k){
            k=0;
            for(int j=0;j<i;j++){
                if(A[j]>A[j+1]){
                    int temp=A[j];
                    A[j]=A[j+1];
                    A[j+1]=temp;
                    k=j;
                }
            }
        }
        return A;
}

 

2.选择排序

int* selectionSort(int* A, int n) {
        // write code here
for(int i=0;i<n-1;i++){ int min=A[i]; int minJ; for(int j=i+1;j<n;j++) if(min>A[j]){ min=A[j];minJ=j; } if(min!=A[i]){ A[minJ]=A[i]; A[i]=min; } } return A; }

 

3.插入排序

int* insertionSort(int* A, int n) {
       for(int i=1;i<n;i++){
           int key=A[i];
           int j;
           for(j=i-1;j>=0&&key<A[j];j--)
               A[j+1]=A[j];
           A[j+1]=key;
       }
       return A;
}

2.O(N*logN)排序算法

1.归并排序

void merge1(int* A,int p,int q,int r) { int MAX=2147483647; int arr1[q-p+2]; int arr2[r-q+1]; for(int i=p;i<=q;i++) arr1[i-p]=A[i]; arr1[q-p+1]=MAX; for(int i=q+1;i<=r;i++) arr2[i-q-1]=A[i]; arr2[r-q]=MAX; int i1=0,i2=0; for(int i=p;i<=r;i++){ if(arr1[i1]<=arr2[i2]) A[i]=arr1[i1++]; else A[i]=arr2[i2++]; } } int* mergeSort1(int* A,int p,int r){ if(p<r){ int q=(p+r)/2; mergeSort1(A,p,q); mergeSort1(A,q+1,r); merge1(A,p,q,r); } return A; }

 

 2.快速排序

void exchange(int* a1,int* a2){
        int temp=*a1;
        *a1=*a2;
        *a2=temp;
    }
    int partition(int* A,int p,int r){
        int key=A[r];
        int i=p-1;
        for(int j=p;j<r;j++){
            if(A[j]<key){
                i++;
                exchange(A+j,A+i);
            }
        }
        exchange(A+i+1,A+r);
        return i+1;
    }
    int* quickSort1(int* A,int p,int r){
        if(p<r){
            int q=partition(A,p,r);
            quickSort1(A,p,q-1);
            quickSort1(A,q+1,r);
        }
        return A;
    }
    int* quickSort(int* A, int n) {
        // write code here
        return quickSort1(A,0,n-1);
    }

 3.shell排序

int* shellSort(int* A, int n) {
        // write code here
       for(int h=n/2;h>0;h/=2){
       for(int i=h;i<n;i++){
           int key=A[i];
           int j;
           for(j=i-h;j>=0&&key<A[j];j-=h){
               A[j+h]=A[j];
           }
           A[j+h]=key;
       }
       }
       return A;
    }

 4.堆排序

void swap(int *a,int* b){
        int temp=*b;
        *b=*a;
        *a=temp;
    }
    
    void percDown(int* A,int i,int N){
        int parent,child;
        int key=A[i];
        for(parent=i;parent*2+1<N;parent=child){
            child=parent*2+1;
            if((child!=N-1)&&(A[child]<A[child+1]))
                child++;
            if(key>=A[child]) break;
            else
                A[parent]=A[child];
        }
        A[parent]=key;
    }
  // S(n)=O(1)
int* heapSort(int* A, int n) { // write code here //从最后一个父节点向上建堆 for(int i=n/2-1;i>=0;i--) percDown(A,i,n); for(int i=n-1;i>0;i--){ swap(A,A+i); percDown(A,0,i); } return A; } }

 3.空间复杂度分析

 O(1):冒泡排序,选择排序,插入排序,希尔排序,堆排序

 O(n):归并排序

 不确定:快速排序,与基准的选择和划分实现有关。

4.排序算法的稳定性

 稳定性:指相同的元素在排序后其先后顺序不变。

 稳定算法:冒泡,插入,归并,计数,基数,桶排序

 不稳定算法:选择,快速,希尔,堆排序

5.关于快速排序的说明

  快速排序并不一定比归并和堆排序优良,在最好情况下,他们的复杂度相同,只是快排的常量系数较小。

6.工程上的排序

  1.工程上使用综合排序

  2.数组小时,一般会使用常量系数低的插入排序

  3.数组较大时,考虑快排等N*logN排序。