#include <stdlib.h>
int mergesort(int p[], int n);
extern int insertsort(int p[], int n);
extern int stablesort(int p[], int n);
static int merge_sort(int p[], int swap[], int n, int count);
static int merge(int work[], int swap[], int m, int n, int flag);
/*
* 归并排序算法在 1938 年由 IBM 发明并在电动整理机上实现。
* 在 1945 年由 J. von Neumann 首次在 EDVAC 计算机上实现。
* 稳定,需要与序列同等大小的辅助空间。这里实现的是两路归并算法。
*/
#define IN 1
#define OUT 0
int mergesort(int p[], int n)
{
int op=0;
int * work=p;
int * swap;
int i,j,w;
int count=0; /* 初始计数为偶数 */
if (n<=16)
return insertsort(work,n);
swap=(int*)calloc(n,sizeof(int));
if (swap==NULL)
return 0;
for(i=0;i+7<n;i+=8)
op+=insertsort(work+i,8);
if (i<n)
op+=insertsort(work+i,n%8);
for(i=8;i<n;i*=2) { /* i 为路段长度 */
w=i*2; /* w 为路段长度乘以归并的路数 */
for(j=0;j+w-1<n;j+=w)
/* 平衡的两路归并 */
op+=merge(work+j,swap+j,i,w,count);
if (i+j<n)
/* 不平衡的两路归并 */
op+=merge(work+j,swap+j,i,n%w,count);
else
/* 换入或换出剩余的一个路段 */
op+=merge(work+j,swap+j,n%w,n%w,count);
count++; /* 计数增加 */
}
if (count%2) /* 计数为奇数 */
for (i=0;i<n;i++)
work=swap;
free(swap);
return op;
}
/*
* 两路归并过程。
*/
static int merge(int work[], /* 工作空间,就是要归并的列表 */
int swap[], /* 交换空间,不小于工作空间 */
int m, /* 前半部分列表长度和后半部分列表的开始位置 */
int n, /* 列表总长度 */
int flag) /* 换入换出标志 */
{
int *src, *dest;
int i=0, j=m, t=0;
flag%=2;
if (flag==OUT) {
src=work;
dest=swap;
}
else { /* flag==IN */
src=swap;
dest=work;
}
while (i<m && j<n) {
if (src <= src[j]) {
dest[t] = src;
t++;
i++;
} else {
dest[t] = src[j];
t++;
j++;
}
}
while (i<m) {
dest[t] = src;
i = i++;
t = t++;
}
while (j<n) {
dest[t] = src[j];
j++;
t++;
}
return n;
}
/**************************************/
/* 下面是递归实现,留做参考 */
/**************************************/
int mergeSort(int p[], int n)
{
int op=0;
int * temp;
if (n<=16)
return insertsort(p,n);
temp=(int*)calloc(n,sizeof(int));
if (temp==NULL)
return 0;
op=merge_sort(p,temp,n,0);
free(temp);
return op;
}
static int merge_sort(int work[], int swap[], int n, int count)
{
int op=0;
int i, m;
count++; /* 计数增加 */
m=n/2;
if(n<=8) {
op+=insertsort(work,n);
if (count%2==0) /* 计数为偶数 */
for (i=0;i<n;i++)
swap=work;
} else {
op+=merge_sort(work,swap,m,count);
op+=merge_sort(work+m,swap+m,n-m,count);
op+=merge(work,swap,m,n,count);
}
return op;
}
两路归并排序算法
最新推荐文章于 2022-07-13 17:52:38 发布
以下内容为程序代码: