并归排序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/IceS2388627880/article/details/60318190
***并归排序***

基本思想:首先将待排序文件看成n个长度为1的有序子文件,得到n/2个长度为2的有序子文件;然后再把这n/2个有序的子文件两两归并,如此反复,直到最后得到一个长度为n的有序文件为止。

核心是相邻的两个数组。分割比较难。

#if ! defined(MERGESORT_H)
#define MERGESORT_H

#include<stdio.h>

#define MAXSIZE 100
typedef int KeyType;//关键字类型用来比较
typedef char InfoType;//其他类型的信息
typedef struct{
	KeyType key;//排序用的关键字
	InfoType other;//其他附属信息
}RecType;//记录类型
typedef RecType SeqList[MAXSIZE+1];//+1用来使[0]作为哨兵,但是在实际使用中往往不能使[0]作为哨兵
/*
***并归排序***
基本思想:首先将待排序文件看成n个长度为1的有序子文件,得到n/2个长度为2的有序子文件;然后再把这n/2个有序的子文件两两归并,如此反复,直到最后得到一个长度为n的有序文件为止。
*/
void Merge(RecType R[],RecType MR[],int low,int m,int high){
	//R[]源数据,MR[]目标数据,low低边的索引,high高边的索引。
	//将数组中前后相邻的两个有序序列归并为一个有序序列
	int i,j,k;
	i=low;
	j=m+1;
	k=low;//目标索引
	
	while(i<=m && j<=high){//两者同时有元素
		if(R[i].key<=R[j].key)
			MR[k++]=R[i++];
		else
			MR[k++]=R[j++];
	}

	while(i<=m)//低地址一端有元素
		MR[k++]=R[i++];

	while(j<=high)//高地址一端有元素
		MR[k++]=R[j++];
}

void MergePass(RecType R[],RecType MR[],int len,int n){
	int i,j;
	//最后元素下标为n-1
	for(i=0;i+2*len-1<n;i=i+2*len){//i+2*len-1.相邻两个元素长度相等的数组同时存在
		//第一个的长度:i+len-1-(i)+1=len;第二个的长度i+2*len-1-(i+len)+1=len
		Merge(R,MR,i,i+len-1,i+2*len-1);//[a,b]元素个数等于b-a+1;[a,b)元素个数等于b-a+1。
	}

	if(i+len-1<n){//i+len-1< n <=i+2*len-1,大于一个长度,小于两个长度
		Merge(R,MR,i,i+len-1,n-1);
	}else{
		//小于一个长度
		for(j=i;j<n;j++)
			MR[j]=R[j];
	}
}

void MergeSort(RecType R[],RecType MR[],int n){
	//R[]是源数组,MR[]是目标数组,n是数组元素个数
	int len=1;
	while(len<n){//元素个数没有问题
		MergePass(R,MR,len,n);
		len*=2;
		MergePass(MR,R,len,n);
		len*=2;
	}
}
void MergeSortTest(){
	RecType SeqList[]={{5,'A'},{4,'B'},{3,'C'},{2,'D'},{1,'E'},{6,'F'},{7,'G'},{5,'H'},{2,'I'},{8,'J'},
						 {9,'K'},{10,'L'},{11,'M'},{12,'N'},{13,'O'},{14,'P'},{1,'Q'},{2,'R'},{3,'S'},{20,'T'}};

	RecType MR[10];	
	int i,n=10;
	printf("并归排序前:\n");
	for(i=0;i<n;i++){
		printf("%2d,%c ",SeqList[i].key,SeqList[i].other);
		if(i%10 == 9) 
			printf("\n");
	}
	printf("\n");

	MergeSort(SeqList,MR,10);

	printf("并归排序后:\n");
	for(i=0;i<n;i++){
		printf("%2d,%c ",SeqList[i].key,SeqList[i].other);
		if(i%10 == 9) 
			printf("\n");
	}
	printf("\n");
}

void main(){
	
	MergeSortTest();

}
#endif
运行结果:


猜你喜欢

转载自blog.csdn.net/IceS2388627880/article/details/60318190
今日推荐