数据结构复习指导之归并排序、基数排序、计数排序

目录

1.归并排序

1.1二路归并操作的功能

1.2算法思想

1.3代码分析

1.4性能分析

2.基数排序

2.1算法思想

2.2基数排序的中间过程的分析

2.3性能分析

3.计数排序

3.1算法思想

3.2代码分析

3.3性能分析

知识回顾


1.归并排序

1.1二路归并操作的功能

归并排序与上述基于交换、选择等排序的思想不一样,归并的含义是将两个或两个以上的有序表合并成一个新的有序表

假定待排序表含有n个记录,则可将其视为n个有序的子表,每个子表的长度为1,然后两两归并,得到\left \lceil n/2 \right \rceil个长度为 2 或 1 的有序表;

继续两两归并……如此重复,直到合并成一个长度为n的有序表为止,这种排序算法称为二路归并排序。

图8.9所示为二路归并排序的一个例子,经过三趟归并后合并成了有序序列。

1.2算法思想

Merge()的功能是将前后相邻的两个有序表归并为一个有序表。

设两段有序表 A[low..mid]、A[mid+1..high]存放在同一顺序表中的相邻位置,先将它们复制到辅助数组 B中。

每次从B的两段中取出一个记录进行关键字 的比较,将较小者放入中,当B中有一段的下标超出其对应的表长(即该段的所有元素都已复制到中)时,将另一段的剩余部分直接复制到A中。

1.3代码分析

算法如下:

ElemType *B=(ElemType *)malloc((n+1)*sizeof(ElemType));//辅助数组 B
void Merge(ElemType A[],int low,int mid,int high){
//表A的两段A[low..mid]和a[mid+1..high]各自有序,将它们合并成一个有序表
    int i,j,k;
    for(k=low;k<=high;k++)
        B[k]=A[k];                //将A中所有元素复制到B中
    for(i=low,j=mid+1,k=i;i<=mid && j<=hiqh;k++){
        if(B[i]<=B[j])            //比较B的两个段中的元素
            A[k]=B[i++];          //将较小值复制到A中
        else
            A[k]=B[j++];
    }
    while(i<=mid)  A[k++]=B[i++]; //若第一个表未检测完,复制
    while(j<=high) A[k++]=B[j++]; //若第二个表未检测完,复制
}

注意:在上面的代码中,最后两个 while 循环只有一个会执行。 

一趟归并排序的操作是,调用\left \lceil n/2h \right \rceil次算法 merge(),将 L[1..n]中前后相邻且长度为h的有序段进行两两归并,得到前后相邻、长度为2h的有序段,整个归并排序需要进行\left \lceil log_{2}n \right \rceil趟。

递归形式的二路归并排序算法是基于分治的,其过程如下。

  • 分解:将含有n个元素的待排序表分成各含n/2个元素的子表,采用二路归并排序算法对两个子表递归地进行排序。
  • 合并:合并两个已排序的子表得到排序结果。
void MergeSort(ElemType A[],int low,int high){
    if(low<high){
        int mid=(low+high)/2;    //从中间划分两个子序列
        MergeSort(A,low,mid);    //对左侧子序
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心碎烤肠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值