用顺序线性表实现归并排序

思路:分治思想,将线性表不断对半拆分,拆到只剩一个元素时就进行从小到大归并,递归实现
代码

#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;
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值