数据结构-归并排序

第1关:归并排序的递归算法

编程要求

根据提示,在右侧编辑器 Begin-End 区间补充代码,完成函数的定义,实现归并排序的递归算法,具体要求如下:

  • void Merge(SqList &L,int s,int m, int e);//将顺序表L的局部r[s,m]和r[m+1,e]合并到tmp,并保证tmp有序,然后再拷贝回r[s,m] ,归并操作时间复杂度:O(e-m+1),即O(n)
  • void MergeSort(SqList &L,int s,int e);//对顺序表L做归并排序,要求调用show函数打印每一趟排序的结果

测试说明

平台会对你编写的代码进行测试:

测试输入: 4

输入说明: 第一行为整数n,代表待排序的整数的个数,同时也代表随机数的种子,系统自动产生n个整数。

#include<iostream>
#include<fstream>
using namespace std;
#include <time.h>
#define MAXSIZE 100 //顺序表的最大长度
#define OK 0
#define ERROR -1
typedef char* InfoType;
typedef struct {
    int key;//关键字项
    InfoType otherinfo;//其他数据项
}RedType;//记录类型                         
typedef struct {
    RedType r[MAXSIZE+1];//r[0]闲置或用做哨兵单元
    int length;//顺序表长度
}SqList;//顺序表类型
void InitSqList(SqList &L) ;//初始化一个空的顺序表L
void InsertSqList(SqList &L) ;//将待排序记录依次插入顺序表L
void show(SqList L) ;//打印顺序表L
void Merge(SqList &L,int s,int m, int e);//将顺序表L的局部r[s,m]和r[m+1,e]合并到tmp,并保证tmp有序,然后再拷贝回r[s,m] ,归并操作时间复杂度:O(e-m+1),即O(n) 
void MergeSort(SqList &L,int s,int e);//对顺序表L做归并排序,要求调用show函数打印每一趟排序的结果
int main() 
{    
    SqList L;
    InitSqList(L);
    InsertSqList(L);  //测试数据  
    show(L);         //打印初始待排序序列
    MergeSort(L,1,L.length);
    return OK;
}
//初始化一个空的顺序表L
void InitSqList(SqList &L) {
    L.length = 0;
}
//将待排序记录依次插入顺序表L
void InsertSqList(SqList &L) {
    int n;//待排序记录的个数
    cin>>n;
    srand(n);
    if(n > MAXSIZE) exit(ERROR);
    for(int i=1; i<=n; ++i) {
        L.r[i].key = rand() % 100;
        ++L.length;
    }
}
//打印顺序表L
void show(SqList L) {
    for(int i=1; i<=L.length; ++i)
        cout<<L.r[i].key<<" ";
    cout<<endl;
}
//将顺序表L的局部L.r[s,m]和L.r[m+1,e]合并到tmp,并保证tmp有序,然后再拷贝回L.r[s,m] //归并操作时间复杂度:O(e-m+1),即O(n) 
void Merge(SqList &L,int s,int m, int e)
{
    /*-------------代码开始------------------*/    
    int pb = 0; 
    int p1 = s,p2 = m+1; 
    RedType *tmp;            
    tmp=(RedType *)malloc((e-s+1)*sizeof(RedType));  //动态分配空间
    while( p1 <= m && p2 <= e)
    { 
        if( L.r[p1].key  < L.r[p2].key ) 
            tmp[pb++] = L.r[p1++]; 
        else 
            tmp[pb++] = L.r[p2++];
    }
    while( p1 <= m) 
        tmp[pb++] = L.r[p1++]; 
    while( p2 <= e) 
        tmp[pb++] = L.r[p2++];
    for(int i = 0;i < e-s+1; ++i)
        L.r[s+i] = tmp[i];
    free(tmp); 
    /*-------------代码结束------------------*/
}
//对顺序表L做归并排序,要求调用show函数打印每一趟排序的结果
void MergeSort(SqList &L,int s,int e)
{     
    /*-------------代码开始------------------*/     
    if( s < e) 
    {
        int m = s + (e-s)/2; 
        MergeSort(L,s,m); 
        MergeSort(L,m+1,e); 
        Merge(L,s,m,e); 
        show(L);
    }
    /*-------------代码结束------------------*/
}

 第2关:归并排序的非递归算法

编程要求

根据提示,在右侧编辑器补充代码。

  • void MergePass(SqList &L,int length); //一趟二路归并排序
  • void MergeSort(SqList &L); //二路归并的非递归算法

测试说明

测试输入: 7

输入说明: 第一行为整数n,代表待排序的整数的个数,同时也代表随机数的种子,系统自动产生n个整数。

 

#include<iostream>
#include<fstream>
using namespace std;
#include <time.h>
#define MAXSIZE 100 //顺序表的最大长度
#define OK 0
#define ERROR -1
typedef char* InfoType;
typedef struct {
    int key;//关键字项
    InfoType otherinfo;//其他数据项
}RedType;//记录类型                         
typedef struct {
    RedType r[MAXSIZE+1];//r[0]闲置或用做哨兵单元
    int length;//顺序表长度
}SqList;//顺序表类型
void InitSqList(SqList &L) ;//初始化一个空的顺序表L
void InsertSqList(SqList &L) ;//将待排序记录依次插入顺序表L
void show(SqList L) ;//打印顺序表L
void Merge(SqList &L,int s,int m, int e);//将数组a的局部a[s,m]和a[m+1,e]合并到tmp,并保证tmp有序,然后再拷贝回a[s,m] ,归并操作时间复杂度:O(e-m+1),即O(n) 
void MergePass(SqList &L,int length);    //一趟二路归并排序
void MergeSort(SqList &L);            //二路归并的非递归算法
int main() 
{    
    SqList L;
    InitSqList(L);
    InsertSqList(L);  //测试数据      
    MergeSort(L);
    return OK;
}
//初始化一个空的顺序表L
void InitSqList(SqList &L) {
    L.length = 0;
}
//将待排序记录依次插入顺序表L
void InsertSqList(SqList &L) {
    int n;//待排序记录的个数
    cin>>n;
    srand(n);
    if(n > MAXSIZE) exit(ERROR);
    for(int i=1; i<=n; ++i) {
        L.r[i].key = rand() % 100;
        ++L.length;
    }
}
//打印顺序表L
void show(SqList L) {
    for(int i=1; i<=L.length; ++i)
        cout<<L.r[i].key<<" ";
    cout<<endl;
}
void Merge(SqList &L,int s,int m, int e)
{
    //将顺序表L的局部L.r[s,m]和L.r[m+1,e]合并到tmp,并保证tmp有序,然后再拷贝回L.r[s,m] //归并操作时间复杂度:O(e-m+1),即O(n) 
    /*-------------代码开始------------------*/    
    if(e-s+1 <= 1)
        return;
    int pb = 0; 
    int p1 = s,p2 = m+1; 
    RedType *tmp;            
    tmp=(RedType *)malloc((e-s+1)*sizeof(RedType));  //动态分配空间
    while( p1 <= m && p2 <= e)
    { 
        if( L.r[p1].key  < L.r[p2].key ) 
            tmp[pb++] = L.r[p1++]; 
        else 
            tmp[pb++] = L.r[p2++];
    }
    while( p1 <= m) 
        tmp[pb++] = L.r[p1++]; 
    while( p2 <= e) 
        tmp[pb++] = L.r[p2++];
    for(int i = 0;i < e-s+1; ++i)
        L.r[s+i] = tmp[i];
    free(tmp); 
    /*-------------代码结束------------------*/
} 
void MergePass(SqList &L,int length)    //一趟二路归并排序
{    /*-------------代码开始------------------*/     
    int i;
    for (i=1;i+2*length-1<=L.length ;i=i+2*length)    //归并length长的两相邻子表
        Merge(L,i,i+length-1,i+2*length-1);
    if (i+length-1<=L.length)                    //余下两个子表,后者长度小于length
        Merge(L,i,i+length-1,L.length);        //归并这两个子表
    /*-------------代码结束------------------*/
}
//对顺序表L做非递归的归并排序,要求调用show函数打印每一趟排序的结果
void MergeSort(SqList &L)            
{    show(L);         //打印初始待排序序列
    /*-------------代码开始------------------*/   
    int length;
    for (length=1;length<=L.length ;length=2*length)
    {
        MergePass(L,length);
        show(L);
    }
    /*-------------代码结束------------------*/
}

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值