思路:分治思想,将线性表不断对半拆分,拆到只剩一个元素时就进行从小到大归并,递归实现
代码:
#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define LIST_INIT_SIZE 200 //线性表存储空间的初始分配量
#define LISTINCREMENT 20 //线性表存储空间的分配增量
typedef int Status;
typedef int ElemType;
typedef struct{
ElemType *elem; //存储空间基址
int length; //当前长度
int listsize; //当前分配的存储容量
}SqList;
Status InitList_Sq(SqList &L){
//构造一个空的线性表L
L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!L.elem) exit(OVERFLOW); //存储分配失败
L.length=0; //空表长度为0
L.listsize=LIST_INIT_SIZE; //初始存储容量
return OK;
}
Status ListInsert_Sq(SqList &L,int i,ElemType e){
//在顺序表L中第i个位置之前插入新的元素e
if(i<1||i>L.listsize+1) return ERROR; //i值不合法
if(L.length>=L.listsize){ //当前存储空间已满,增加分配
ElemType *newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
if(!newbase) exit(OVERFLOW);
L.elem=newbase; //新基址
L.listsize+=LISTINCREMENT; //增加存储容量
}
ElemType *q=&(L.elem[i-1]),*p;
for(p=&(L.elem[L.length-1]);p>=q;--p) *(p+1)=*p;
*q=e;
++L.length;
return OK;
}//ListInsert_Sq
void MergeList_Sq(SqList La,SqList Lb,SqList &Lc){
//已知顺序线性表La和Lb的元素按值非递减排列
//归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列
ElemType *pa,*pb,*pc,*pa_last,*pb_last;
pa=La.elem;pb=Lb.elem;
Lc.listsize=Lc.length=La.length+Lb.length;
pc=Lc.elem=(ElemType*)malloc(Lc.listsize*sizeof(ElemType));
if(!Lc.elem) exit(OVERFLOW);
pa_last=La.elem+La.length-1;
pb_last=Lb.elem+Lb.length-1;
while(pa<=pa_last&&pb<=pb_last){
if(*pa<=*pb) *pc++=*pa++;
else *pc++=*pb++;
}
while(pa<=pa_last)*pc++=*pa++;
while(pb<=pb_last)*pc++=*pb++;
}//MergeList_Sq
void PrintList_Sq(SqList L){
//输出线性表L中的元素
ElemType *p;
for(p=L.elem;p<L.elem+L.length;++p)
printf("%d ",*p);
printf("\n");
}//PrintList_Sq
Status DivList(SqList L,SqList &La,SqList &Lb){
//将线性表L对半分解成两个线性表
if(L.length<=1) return ERROR;
ElemType *p,*pa,*pb;
La.listsize=La.length=L.length/2;
Lb.listsize=Lb.length=L.length-La.length;
pa=La.elem=(ElemType*)malloc(La.listsize*sizeof(ElemType));
pb=Lb.elem=(ElemType*)malloc(Lb.listsize*sizeof(ElemType));
for(p=L.elem;p<=&(L.elem[La.length-1]);)
*pa++=*p++;
while(p<=&(L.elem[L.length-1])) *pb++=*p++;
return OK;
}
void Merge_Sort(SqList L,SqList &Ls){
//归并排序,排序后的线性表为Ls
if(L.length==1){//当线性表被拆到只有一个元素时,结束递归
Ls=L;
return ;
}
SqList La,Lb,Lc,Ld;
DivList(L,La,Lb);//将线性表L拆分成La和Lb
Merge_Sort(La,Lc);
Merge_Sort(Lb,Ld);
MergeList_Sq(Lc,Ld,Ls);
}
int main(){
SqList L,La,Lb,Ls;
InitList_Sq(L);
int a;
for(int i=1;i<=100;i++){
a=rand()%200;//产生0到199之间的随机数进行测试
ListInsert_Sq(L,i,a);
}
printf("初始序列:\n");
PrintList_Sq(L);
Merge_Sort(L,Ls);
printf("排序后的序列:\n");
PrintList_Sq(Ls);
return 0;
}