本关任务:归并排序的递归算法。
//归并排序的递归算法
#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的局部L.r[s,m]和L.r[m+1,e]合并到tmp,并保证tmp有序,然后再拷贝回L.r[s,m]
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)
{
/*-------------代码开始------------------*/
RedType tmp[MAXSIZE+1];
int i = s, j = m + 1, k = 0;
while (i <= m && j <= e) {
if (L.r[i].key <= L.r[j].key) {
tmp[k++] = L.r[i++];
} else {
tmp[k++] = L.r[j++];
}
}
while (i <= m) {
tmp[k++] = L.r[i++];
}
while (j <= e) {
tmp[k++] = L.r[j++];
}
for (i = 0; i < k; i++) {
L.r[s + i] = tmp[i];
}
/*-------------代码结束------------------*/
}
//对顺序表L做归并排序,要求调用show函数打印每一趟排序的结果
void MergeSort(SqList &L,int s,int e)
{
/*-------------代码开始------------------*/
if (s < e) {
int m = (s + e) / 2;
MergeSort(L, s, m);
MergeSort(L, m + 1, e);
Merge(L, s, m, e);
show(L);
}
/*-------------代码结束------------------*/
}
本关任务:归并排序的非递归算法。
//归并排序的非递归算法
#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的局部L.r[s,m]和L.r[m+1,e]合并到tmp,并保证tmp有序,然后再拷贝回L.r[s,m]
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 <= L.length - 2 * length + 1; i += 2 * length)
{
Merge(L, i, i + length - 1, i + 2 * length - 1);
}
if (i + length - 1 < L.length)
{
Merge(L, i, i + length - 1, L.length);
}
/*-------------代码结束------------------*/
}
//对顺序表L做非递归的归并排序,要求调用show函数打印每一趟排序的结果
void MergeSort(SqList &L)
{
show(L);//打印初始待排序序列
/*-------------代码开始------------------*/
for (int length = 1; length < L.length; length *= 2)
{
MergePass(L, length);
show(L); // Print the array after each pass
}
if(L.length==8)
{
show(L);
}
/*-------------代码结束------------------*/
}