第8章学习小结

      第8章学习了排序(主要是内部排序),可以分为插入排序、交换排序、选择排序、归并排序。内部排序的过程是一个逐步扩大记录的有序序列长度的过程。

      排序算法效率的评价指标有两个方面:执行时间和辅助空间

   (1)执行时间:比较次数和移动次数都应该尽可能少

   (2)辅助空间:理想的空间复杂度为O(1),即算法执行期间所需要的辅助空间与待排序的数据量无关。

 

一、插入排序

  直接插入排序(基于顺序查找)

  课本P237页 例8.1 手工实现直接插入排序

void InsertSort(SqList &L)
{//对顺序表L做直接插入排序
    for(int i=2 ; i<L.length ; ++i) 
    {
        if(L.r[i].key < L.r[i-1].key)        //小于,需将r[i]插入有序子表
        {
            L.r[0] = L.r[i] ;                    //将待插入的记录暂存到监视哨中
            L.r[i] = L.r[i-1] ;                  //r[i-1]后移
            for(int j=i-2 ; L.r[0].key < L.r[j].key ; --j) //从后往前寻找插入位置
            {
                L.r[j+1] = L.r[j] ;            //记录逐个后移,直到找到插入位置
             }
             L.r[j+1] = L.r[0] ;              //将r[0]即原r[i],插入到正确位置
         }
}

(1)时间复杂度:O(n*n)

(2)空间复杂度:O(1)

(3)算法特点:稳定排序,算法简便,更适合于除湿机路基本有序(非降序)的情况。

 

  折半插入排序(基于折半查找)

  在插入第i个记录时,需要经过log2n次比较,才能确定它应插入的位置

  需要循环n-1次,每次先使用折半查找法,查找r[i]的插入位置,然后将r[i]插入表长为i-1的有序序列中,直到将r[n]插入表长为n-1的有序序列为止。

(1)时间复杂度:O(n*n)

(2)空间复杂度:O(1) (和直接插入排序相同,辅助空间只需要r[0])

(3)算法特点:稳定排序,只能用于顺序结构,适合初始记录无序、n较大的情况。

 

  希尔排序(缩小增量排序)

  课本P240 例8.2 手工实现排序

  希尔排序:第一趟取增量d1(d1<n)把全部记录分成d1个组,所有间隔为d1的记录分在同一组,在各个组中进行直接插入排序

                    第二趟取增量d2(d2<d1),重复上述的分组和排序

                    依次类推,直到所取的增量dt = 1,所有记录在同一组中进行直接插入排序为止。

(1)时间复杂度:O(n3/2)

(2)空间复杂度:O(1)(和前面一样,只需要一个辅助空间r[0])

 

二、交换排序

  冒泡排序

  课本P242 例8.3 手工实现排序

  冒泡排序:在每一趟中,将每个记录的关键字与下一个记录相比较,如果L.r[i].key > L.r[i+1].key,则交换两个记录。依次类推,直到比较完第n-1个记录和第n个记录为止,这样就完成了第一趟冒泡排序。此时关键字最大的记录处于正确的位置(第n个)。

                    然后进行第二趟冒泡排序,对前n-1个记录进行同样的操作,结果是关键字次大的记录处于第n-1个位置上。

                    重复这样的操作,直到在某一趟排序过程中没有进行过交换记录的操作,说明序列已全部达到排序要求。

 (1)时间复杂度:O(n*n)

 (2)空间复杂度:O(1)(在交换时只需要一个辅助空间用来暂存记录)

 (3)算法特点:稳定排序,当初始记录无序、n较大时,不宜采用冒泡排序

 

  快速排序

  课本P244 例8.4 手工实现排序

  快速排序采用 “分治法” 策略把一个序列分为较小和较大的两个子序列,然后递归地排序两个子序列。

  快速排序:预处理:R(low).key,R(high).key 和 R((low+high)/2).key三者取中

                    挑选基准值:从数列中挑出一个元素,称作 “基准”

                    分割:重新排序序列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(与基准值相等的数可以到任何一边)。在这个分割结束之后,对基准值的排序就已经完成。

                    递归排序子序列:递归地将小于基准值元素的子序列和大于基准值元素的子序列排序。

 (1)时间复杂度:O(nlog2n)

 (2)空间复杂度:最好情况下 O(log2n),最坏情况下 O(n)

 (3)算法特点:不稳定排序,适合于顺序结构,适用于初始记录无序、n较大的情况

 

三、选择排序

  简单选择排序

  课本P247 例8.5 手工实现排序

  简单选择排序:第一趟从r[1]开始,通过n-1次比较,从n个记录中选出关键字最小的记录,记为r[k],交换r[1]和r[k]

                           第二趟从r[2]开始,通过n-2次比较,从n-1个记录中选出关键字最小的记录,记为r[k],交换r[2]和r[k]

                           依次类推...经过n-1趟,排序完成

void SelectSort(SqList &L)
{
    for(int i=1 ; i<L.length ; ++i)
    {
        k = i ;
        for(int j=i+1 ; j<=L.length ; ++j)
        {//选择关键字最小的记录
            if(L.r[j].key < L.r[k].key)
            {
                k = j ; //k指向此趟排序中关键字最小的记录
             }
        }
         if(k != i)
         {//交换r[i]与r[k]
             t = L.r[i] ;
             L.r[i] = L.r[k] ;
             L.r[k] = t ;
          }
     }
}

 

(1)时间复杂度:O(n*n)

(2)空间复杂度:O(1)(同冒泡排序一样,只有在交换两个记录时需要一个辅助空间)

 

(3)算法特点:不稳定排序

 

  堆排序

  将序列看成是一个完全二叉树,树中所有非终端结点的值均不大于(不小于)其左、右孩子结点的值。

  大根堆(小根堆):堆顶记录的关键字最大(最小)(如果求非降序,需要建立大根堆)

  课本P250、253

(1)时间复杂度:O(nlog2n)

 

(2)空间复杂度:O(1)(仅需要一个记录大小供交换用的辅助存储空间)

(3)算法特点:不稳定排序

 

四、归并排序

  归并排序

  课本P254 例8.8 手工实现排序

  归并排序:设初始序列含有n个记录,则可看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到 n/2 个长度为2或1的有序子序列;再两两归并,重复操作,直到得到一个长度为n的有序序列为止。

 (1)时间复杂度:O(nlog2n)

 (2)空间复杂度:O(n)(用顺序表实现归并排序时,需要和待排序记录个数相等的辅助存储空间)

 (3)算法特点:稳定排序

 

posted @ 2020-07-12 14:30  咕咕鸽子王  阅读(180)  评论(0编辑  收藏  举报