計算機考研之數據結構-排序

數據結構-排序

重要概念

定義

對元素進行重拍使得其關鍵字知足遞增或者遞減的過程。性能

  • 輸入:n個記錄\(R_1,\cdots,R_n\),對應關鍵字爲\(k_1,\cdots,k_n\)
  • 輸出:一個輸入序列的重拍\(R_1^{'} ,\cdots,R_n^{'}\)使得\(k_1^{'}\leq\cdots\leq k_n^{'}\),比較符號能夠改變。

穩定性

對於關鍵字相同的兩個元素,若是排序先後順序不變即知足穩定性。優化

內部性與外部性

  • 內部排序:排序過程當中全部元素都在內存中。
  • 外部排序:排序過程當中元素要在內外存中交換。

說明

如下例子都以順序表爲例。spa

插入類

插排將序列分爲兩個部分,有序序列和無序的序列。而後從無序序列中拿出一個元素插入到有序序列中便可。code

直接插入排序

void Sort(int A[], int len){
    for(int i=1; i<len; i++){
        if(A[i]<A[i-1]){ //判斷是否須要向前插入
            int temp = A[i];
            for(int j=i-1; temp<A[j]; j--) //找到插入位置
                A[j+1]=A[j]; // 爲插入的元素挪位置
            A[j+1]=temp;
        }
    }
}

性能分析:
空間:O(1)。
時間:最好O(n),最壞O(n^2),平均O(n^2)。
穩定性:穩定。排序

折半插入排序

由於插入的序列是有序的,因此能夠使用折半查找節約時間。遞歸

void sort(int A[], int len){
    for(int i=1; i<len; i++){
        int temp = A[i];
        int low=0;int high=i-1;
        while(low<=high){
            int mid=(low+high)/2;
            if(A[mid]>temp) high=mid-1;
            else low=mid+1;
        }
        for(int j=i-1; j>high; j--) //找到插入位置
            A[j+1]=A[j]; // 爲插入的元素挪位置
        A[high]=temp;  
    }
}

性能分析:
空間:O(1)。
時間:平均O(n^2)。
穩定性:穩定。內存

希爾排序

希爾排序將序列按照必定的長度切分爲多個子序列,對子序列進行插入排序,再對整個序列進行插入排序it

void Sort(int A[], int len){
    for(int dk/len; dk>=1;dk=dk/2){
        for(int i=dk+1;i<=n;i++){
            if(A[i]<A[i-dk]){
            }
        }
    }
}

性能分析:
空間:O(1)。
時間:通常約爲(n^1.3),最壞O(n^2)。
穩定性:不穩定。io

交換類

冒泡排序

冒泡的排序關鍵在於每一輪都會把第i大的那個關鍵字排到有序的位置上。

void sort(int A[], int len){
    for(int i=0;i<len-1;i++)
        for(int j=0;j<len-1-i;j++)
            if(A[j]>A[j+1]){
                int temp = A[j];
                A[j]=A[j+1];
                A[j+1]=temp;
            }
}

加入flag來優化最好狀況:

void sort(int A[], int len){
    for(int i=0;i<len-1;i++){
        int flag = 0;
        for(int j=0;j<len-1-i;j++){
            if(A[j]>A[j+1]){
                int temp = A[j];
                A[j]=A[j+1];
                A[j+1]=temp;
                flag=1;
            }
        }
        if(flag==0)
            return;
    }
}

性能分析:
空間:O(1)。
時間:最壞 O(n^2),最好 O(n),平均 O(n^2)。
穩定性:不穩定。

快速排序

int partition(int A[], int lo, int hi){
    int p = A[lo];
    while(lo<hi){
        while(lo<hi && A[hi]>=p) hi--;
        A[lo]=A[hi];
        while(lo<hi && A[lo]<=p) lo++;
        A[hi]=A[lo];
    }
    A[lo]=p;
    return lo;
}

void sort(int A[], int lo, int hi){
    int lo=0; int hi=len-1;
    if(lo<hi){
        int pos=partition(A,lo,hi);
        sort(A,lo,pos-1);
        sort(A,pos+1,hi);
    }
}

性能分析:
空間:即遞歸棧的深度,最好 O(log(n+1)),最壞 O(n),平均 O()
時間:最壞 O(n^2),平均 O(logn)。
穩定性:不穩定。

選擇類

選擇排序

void sort(int A[], int len){
    for(int i=0;i<len-1;i++){
        int min = i;
        for(int j=i+1;j<n;j++)
            if(A[j]<A[min])
                min = j;
        if(min!=i)
            swap(A[i],A[min]);
    }
}

性能分析:
空間:O(1)
時間:O(n^2)。
穩定性:不穩定。

堆排序

void adjust(int A[], int i, int len){
    int child;
    for(; 2*i+1<len; i=child){
        int child = 2*i+1; //leftchild
        if(child<len-1 && A[child+1]>A[child])
            child++; // rightchild
        if(A[i]<A[child])
            swap(A[i],A[child])
        else
            break;   
    }
}

sort(int A[], int len){
    for(int i=len/2-1; i>=0; i--)
        adjust(A,i,len);
    
    for(int i=length-1;i>0;i--){
        swap(A[0],A[i]);
        adjust(A,0,i);
    }
}

性能分析:
空間:O(1)
時間:O(nlogn)。
穩定性:不穩定。

歸併類

歸併排序

int *B=(int *)malloc(n)*sizeof(int);

void merge(int A[], int low, int mid, int high){
    for(int k=low;k<=high;k++)
        B[k]=A[k];
    for(int i=low,int j=mid+1,int k=i;i<=mid&&j<=high;k++){
        if(B[i]<=B[j])
            A[k]=B[i++];
        else 
            A[k]=B[j++];
    }
    while(i<=mid) A[k++]=B[i++];
    while(j<=high) A[k++]=B[j++];
}

void sort(int A[], int low, int high){
    if(low<high){
        int mid=(low+high)/2;
        sort(A,low,mid);
        sort(A,mid+1;high);
        merge(A,low,mid,high);
    }
}

性能分析:
空間:O(n)
時間:最壞最好都是O(nlogn)。
穩定性:穩定。

基數類

基數排序

性能分析:
空間:O(r)。
時間:最壞最好都是O(d(n+r))。
穩定性:穩定。

小結

相關文章
相關標籤/搜索