第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);
}
/*-------------代码结束------------------*/
}