您的位置:首页 > 其它

归并排序(递归与非递归)

2016-03-14 17:49 218 查看
1.递归:

把序列分成元素个数尽量相等的两部分,再将两半分别排序,合并有序的两个序列

//递归
void merge_sort(int *A, int low, int heigh, int *T)
//A为待排序数组,low,high分别为A的上下限(0~n-1),T为辅助数组
{
int i,j,k,mid;

if(heigh-low > 0)
{
mid = low + (heigh-low)/2;
merge_sort(A, low, mid, T);
merge_sort(A, mid+1, heigh, T); //递归

i=low; j=mid+1; k=0;
while(i<=mid || j<=heigh)
{
if(j>heigh || (i<=mid && A[i]<=A[j])) //包含左右数组非空和左非空右空
T[k++] = A[i++]; //左边的复制到辅助数组 T;
else
T[k++] = A[j++]; //右边的复制到辅助数组 T;
}

for(i=low, j=0; i<=heigh; i++, j++)
{
A[i] = T[j]; //将T中排好序的复制回A;
}
}
}

2.非递归:

首先查找数组中自然排序好的序列,两两合并,循环下去,直到不再合并即为有序

void merge(int *A, int l, int m, int r) //合并函数
{
int i=l, j=m+1; //l,m,r分别为两个序列的上下序号,m为分界处,即m为第一个序列的下界,m+1为第二个的上界
int p=0, q;
int *T;
T=(int *)malloc((r-l+1)*sizeof(int)); //辅助数组

if(!T) return;

while(i<=m && j<=r) //分情况合并,与上面递归中效果相同(递归中用了短路或,写起来方便点)
{ //左右非空
if(A[i]<=A[j])
T[p++] = A[i++];
else
T[p++] = A[j++];
}

if(i>m) //左空右非空
{
for(q=j; q<=r; q++)
{
T[p++] = A[q];
}
}
else //左非空右空
{
for(q=i; q<=m; q++)
{
T[p++] = A[q];
}
}

for(p=l, q=0; p<=r; p++, q++) //将T中排好序的复制回A中
{
A[p]=T[q];
}
}

void fun(int *A, int n) //排序,A为待排序数组,n为数组中元素个数
{
int i;
int low, mid, heigh; //low,mid,heigh记录两个合并的序列指针
int flag; //判断是否有序
while(1)
{ flag=1;i=0;
while(i<n-1)
{
low = i;
while(i<n-1 && A[i]<=A[i+1])
{
i++;
}
mid = i++;

while(i<n-1 && A[i]<=A[i+1])
{
i++;
}
heigh = i++;

if(i<=n)
{
merge(A, low, mid, heigh);
flag++; //flag不变则已有序
}
}
if(flag==1) break;

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息