数据结构第十章 排序 总结

排序算法的衡量

时间效率

比较次数与移动次数

空间效率

占内存辅助空间的大小

稳定性

假设 ki 是记录 Ri 中的关键字,kj 是记录 Rj 的中关键字,ki = kj 且在排序前的序列中,Ri 领先于Rj 。若在排序后的序列中 Ri 仍领先于 Rj,则称所用的排序方法是稳定的。

假设 ki 是记录 Ri 中的关键字,kj 是记录 Rj 的中关键字,ki = kj 且在排序前的序列中,Ri 领先于Rj 。若在排序后的序列中 Ri 仍领先于 Rj,则称所用的排序方法是稳定的。

直接插入排序

过程

整个排序过程为 n-1 趟插入。

1.先将序列中第1个记录看成是一个有序子序列。

2.取未排序子序列中的第一个元素,在已排序子序列中按简单顺序查找法(挨个比较)查找插入位置,边查找边移位。(重复此操作直到排序完成)

演示

用一个 n×n 的表格来表示。

[13] 6 3 31 9 27 5 ——-初始
[6 13] 3 31 9 27 5 ——-第一躺
[3 6 13] 31 9 27 5 ——-第二趟
[3 6 13 31] 9 27 5 ——-第三趟
[3 6 9 13 31] 27 5 ——-第四趟
[3 6 9 13 27 31] 5 ——-第五躺
[3 5 6 9 13 27 31] ——-第六躺

分析

时间复杂度: O(n2)

空间复杂度: O(1)

稳定性:稳定

实现

C语言实现

void InsertSort(SqList &L)
{
    int i,j;
    for(i=2; i<=L.length; ++i)
    if( L.r[i].key < L.r[i-1].key )
        { 
            L.r[0]=L.r[i];           // 复制为哨兵
            for(j=i-1; L.r[0].key<L.r[j].key; --j)
                L.r[j+1]=L.r[j];     // 第j个位置上的记录后移 
            L.r[j+1]=L.r[0];         //插入到正确位置
       }
 }

哨兵也可以单独的挑出来 , 数组从零开始。

void InsertSort(SqList &L)
{
    int i,j;
    r_type guard;
    for(i = 1; i <= L.length; ++i)
    if( L.r[i].key < L.r[i-1].key )
        { 
            guard = L.r[i];           // 复制为哨兵
            for(j = i-1; guard.key < L.r[j].key; --j)
                L.r[j+1] = L.r[j];     // 第j个位置上的记录后移 
            L.r[j+1] = guard;         //插入到正确位置
       }
 }

折半插入排序

过程

1.先将序列中第1个记录看成是一个有序子序列。

2.取未排序子序列中的第一个元素,在已排序子序列中按折半查找法查找插入位置,边查找边移位。(重复此操作直到排序完成)

插入位置的规则

当low>high时,low位置就是待插入的位置;

当r[mid]=r[i]时,mid+1位置就是插入位置;

分析

时间复杂度: O(n2) (比直接插入快)

空间复杂度: O(1)

稳定性:稳定

实现(待定)

希尔排序

过程

先将整个待排记录序列分割成若干子序列,分别进行直接插入排序。

待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。

演示

划分序列为 {5,3,1}

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

实现(待定)

冒泡排序(起泡排序)

过程

每趟不断将相邻两记录比较,并按“前小后大” 规则交换

演示

太简单了啊不想演示

这里写图片描述

分析

时间复杂度: O(n2)

空间复杂度: O(1)

稳定性:稳定

实现

C语言实现

void BubbleSort(SqList &L){
    a_type temp;
    for(i = 1; i < L.length; i++){
        c = 0;
        for(j = 1; j <= L.length-i; j++){
            if(L.a[j].key > L.a[j+1].key){
            temp = L.a[j]; 
            L.a[j] = L.a[j+1];
            L.a[j+1] = temp; //交换
            c++;
        }
        if(c == 0) break; //一趟没有发生交换,提前结束排序
    }   
}

快速排序

过程

1.任取一个元素 为中心(支点),一般刚开始取首位元素。

2.所有比它小的元素放在它前面,比它大的元素放在它后面,形成左右两个子表

3.对各子表重新选择中心元素并依此规则调整,直到每个子表的元素只剩一个

演示

太难了我不想演示

这里写图片描述

我又想演示了

  1. high开始往前找比“枢纽”小的数,赋予low处。

  2. low开始往后找比“枢纽”大的数,赋予high处。

  3. 重复1,2步直到low >= high

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

实现

C语言实现

int Partition(SqList &L, int low,  int  high) 
{   //定位“枢纽”
    L.r[0] = L.r[low];    //将“枢纽”值赋予L.r[0]
    while(low < high) 
    { 
        /* 从high开始往前找比“枢纽”小的数,赋予`low`处 */
        while(low < high && L.r[high].key >= L.r[0].key)
            --high;
        L.r[low] = L.r[high];

        /* 从`low`开始往后找比“枢纽”大的数,赋予`high`处 */
        while(low < high && L.r[low].key <= L.r[0].key)  
            ++low;
        L.r[high] = L.r[low];
    }
    L.r[low]=L.r[0];     //将“枢纽”值赋予L.r[low]
    return low;          //返回“枢纽”位置
}

void QSort ( SqList &L, int low,  int  high ) 
{  
    if(low < high)
    {  
        pivotloc = Partition(L, low, high); //pivot:枢纽
        QSort(L, low, pivotloc-1);          //对左子表排序
        QSort(L, pivotloc+1, high);         //对右子表排序
    }
}

简单选择排序

过程

每一趟在 n-i +1个中选出关键码最小的对象, 作为有序序列的第 i 个记录

分析

时间复杂度: O(n2)

空间复杂度: O(1)

稳定性:稳定

演示

这里写图片描述

实现

C语言实现

void SelectSort(SqList &K)
{
    rtype temp;
    for (i=1; i<L.length; ++i)
    { 
        k = i;     //k为当前最小记录的位序
        for(j=i+1;j<=L.length ; j++)
            if(L.r[j].key < L.r[k].key) 
                k=j;  //就是大一学的“戴帽子”法
        if(k != i)
        L.r[i]←→L.r[k];            
    }  
}

树形排序

不考,我就先不写了啊

这里写图片描述

堆排序

堆:n个元素的序列{k1,k2,…,kn},当且仅当满足下列关系时,称为堆:

{kik2ikik2i1


{kik2ikik2i1

前者称为小顶堆(最小堆),后者称为大顶堆(最大堆),即堆顶元素(根)为最小值或最大值。

堆是一个线性结构。

如果将堆序列看成一个完全二叉树的线性存储结构,那么非终端结点的值均小于或大于左右孩子结点的值。

过程

1. 将待排序元素依次输入建立完全二叉树

2. 从最后一个非终端节点(第 n 元素)开始,至第一个元素,若存在比其小(大)的子节点,将其与最小(大)的子节点做替换,堆顶元素为最小(大),输出堆顶元素。

3. 将其与堆中最后一个元素(当前无序序列的最后一个元素)互换,并“剔除”最后一个元素。

4. 重复1,2,3步直到排序完成。

分析

时间复杂度: O(nlog2n)

空间复杂度: O(1)

稳定性:不稳定

适用于n 较大的情况

演示

这里写图片描述

待排序序列{30 60 8 40 70 12 10}

建大顶堆(从小大大排序)

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

归并排序

之前有专门总结:二路归并算法

基数排序

多关键字的排序

高位优先法

划分子序列的思想

低位优先法

分配再收集的思想

基数

d 为分量数。

设关键字的每个分量的取值范围均是:

C0kjCrd1(0j<d)

可能的取值个数 rd 称为基数。

链式基数排序

过程

建立一组关键字链表,用于分配和回收各位关键字;

从低位关键字到高位关键字依次进行分配和回收;

分配:根据当前关键字的取值将记录插入到相应的链表中;

回收:各链表“头尾相连”后回收所有记录作为下次分配的记录序;

演示

待排序序列:{47 82 40 07 59 38 69 05}
这里写图片描述
这里写图片描述

比较

这里写图片描述

快速排序平均状态下最快,但不稳定。

数据量大,要稳定,要快,归并。

好的,继续学kava。

这里写图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
排序作业 选择题(每题2分,共22分)。 1.若表R在排序前已按键值递增顺序排列,则(   )算法的比较次数最少。 A.直接插入排序            B.快速排序     C.归并排序                D.选择排序 2.对各种内部排序方法来说,(   )。 A.快速排序时间性能最佳                             B.归并排序是稳定的排序方法 C.快速排序是一种选择排序                          D.堆排序所用的辅助空间比较大 3.  排序算法的稳定性是指(   )。 A.经过排序之后,能使值相同的数据保持原顺序中的相对位置不变。 B.经过排序之后,能使值相同的数据保持原顺序中的绝对位置不变。 C.排序算法的性能与被排序元素的数量关系不大 D.排序算法的性能与被排序元素的数量关系密切 4. 如下序列中,(   )序列是大顶堆。 A.  {4,5,3,2,1}               B.  {5,3,4,1,2}        C.  {1,2,3,4,5}               D.  {1,2,3,5,4} 5. 若将{3,2,5,4,1}排为升序,则实施快速排序一趟后的结果是(   )(其中,枢轴记录取首记录)。 A.  {1,2,3,4,5}                  B.  {1,2,4,5,3}        C.  {1,3,5,4,2}                  D.  {2,5,4,1,3} . 若将{1,2,3,4,5,6,7,9,8}排为升序,则(   )排序方法的“比较记录”次数最少。 A.  快速排序                   B.  简单选择排序     C.  直接插入排序               D.  冒泡排序 7. 若将{5,4,3,2,1}排为升序,则(   )排序方法的“移动记录”次数最多。 A.  快速排序                                B.  冒泡排序 C.  直接插入排序                       D.  简单选择排序 8. 用简单选择排序将顺序表{2,3,1 ,3′,2′}排为升序,实施排序1趟后结果是{1 ,3,2 ,3′,2′},则排序3趟后的结果是(   )。 A.  {1 ,2,3 ,3′,2′}                       B.  {1 ,2 ,2′,3 ,3′} C.  {1 ,2′,2 ,3 ,3′}                      D.  {1 ,2 ,2′,3′,3 } 9.下列排序算法中,(    )排序在某趟结束后不一定选出一个元素到其最终的位置上。 A.选择             B.冒泡           C.归并           D.堆 10.下列排序算法中,稳定的排序算法是(  )。 A.堆排序                B.直接插入排序   C.快速排序              D.希尔排序 11.堆排序时间复杂度是(    )。 A.O(n*n)                 B.O(n*log n)       C.O(n)                   D.O(log n) 填空题(每空4分,共4分)。 对n个元素进行归并排序,空间复杂度为         。 综合题(共24分)。 1. (共12分)有一组待排序关键字如下: (54,38,96,23,15,72,60,45,83) 分别写出希尔排序(d=5)、快速排序、堆排序、归并排序第一趟升序排序后的结果(其中堆排序的第一趟指序列完成初始建堆、将堆顶元素置为最末位置后其余元素调整为堆的结果)(每个3分)。 希尔排序:   快速排序: 堆排序: 归并排序:  2. (共12分)已知数据序列为(12,5,9,20,6,31,24),对该项数据序列进行排序,分别写出直接插入排序、简单选择排序、快速排序、堆排序、二路归并排序及基数排序第一趟升序排序结果(其中堆排序的第一趟指序列完成初始建堆、将堆顶元素置为最末位置后其余元素调整为堆的结果)(每个2分)。 直接插入排序: 简单选择排序: 快速排序: 堆排序: 二路归并排序: 基数排序:    

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值