C语言排序算法学习笔记——交换类排序

交换类排序:根据序列中两个元素关键字的比较结果来交换他俩在序列中的位置。

冒泡排序:假设待排序表长为n,从后往前(或从前往后)两两比较相邻元素的值,若为逆序(即A[i-1]>A[i])则交换他们,直到序列比较完。我们称它为一趟冒泡,结果将最小的元素交换到待排序序列的第一个位置。下一趟冒泡时,前一趟确定的最小元素不再参与比较,待排序列减少一个元素,每趟冒泡的结果把序列中最小元素放到了序列的最终位置,……,这样最多n-1趟冒泡就能把所有元素排好序。

void BubbleSort(ElemType A[],int n){
    for(i=0;i<n-1;i++){
        bool flag=false;                          //设置标志位 
        for(j=n-1;j>i;j--)                        //一趟冒泡过程 
            if(A[j-1].key>A[j].key){              //将较小的元素向上移动 
                ElemType temp=A[j-1].key;
                A[j-1].key=A[j].key;
                A[j].key=temp;
                flag=true;                        //发生了数据交换,修改标志位 
            }
        if(flag==false) return;                   //如果有一趟没有发生数据交换,表示序列已经完成了排序 
    }
} 

空间复杂度:O(1)。

时间复杂度:在最糟糕的情况下,初始序列是逆序的,时间复杂度为O(n2);在最好的情况下,初始序列是顺序的,时间复杂度为O(n)。

稳定性:当两个关键字相同,if的判断条件不成立,不会发生数据的移动,因此是稳定的。

快速排序:一种基于分治法的排序方法。每一趟快排选择序列中任一个元素作为枢轴(pivot)(通常选择第一个元素),将序列中比枢轴小的元素都移到枢轴前边,比枢轴大的元素都移到枢轴后边。其实现为:

int Partition(ElemType A[],int low,int high){      //一次快速排序,low是待排序起始下标,high是待排序末位下表 
    ElemType pivot=A[low];                         //第一个元素作为枢轴 
    while(low<high){
        while(low<high&&A[high]>=pivot) --high;    //先从末尾往前找到第一个比枢轴小的元素 
        A[low]=A[high];                            //用high的元素替换low的元素 
        while(low<high&&A[low]<=pivot) ++low;      //再从开头往后找到第一个比枢轴大的元素 
        A[high]=A[low];                            //用low的元素替换high的元素 
    }
    A[low]=pivot;                                  //枢轴元素放在最终的位置 
    return low;                                    //返回放枢轴的最终位置 
} 
void QuickSort(ElemType A[],int low,int high){
    if(low<high){
        int pivopos=Partition(A,low,high);
        QuickSort(A,low,pivopos-1);                //分治递归左半部分 
        QuickSort(A,pivopos+1,high);               //分治递归右半部分 
    }
}

时间复杂度:最好情况下O(nlogn),待排序数列越无序,算法效率越高;最坏情况下时间复杂度为O(n2),待排序序列越有序,算法效率越低。

稳定性:不稳定,存在交换关键字。

原文地址:https://www.cnblogs.com/jackliu-timecomplexity/p/10638490.html