归并排序(递归与非递归)
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;
}
}
把序列分成元素个数尽量相等的两部分,再将两半分别排序,合并有序的两个序列
//递归
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;
}
}
相关文章推荐
- 贝叶斯公式
- openGL之混合、抗锯齿---openGL学习笔记(十一)
- Redis分布式锁Java实现
- IOS学习 触摸和手势UITouch 捏合
- 用K-means聚类算法实现音调的分类与可视化
- struts2 标签
- 构建之法阅读笔记01
- ua实现类似 www.taobao.com 在手机上打开自动转变为 m.taobao.com 的域名转换
- dz帖子去掉下载提示和附件名称
- Unity3D面试题整合(看完Unity基础知识就掌握差不多了)
- C++中实现队列类链式存储与栈类链式存储的代码示例
- HDU4771(2013 Asia Hangzhou Regional Contest )
- 升级mysql_upgrade 提示错误FATAL ERROR: Upgrade failed的原因
- CSS模块化基本思想
- js中继承的几种用法总结(apply,call,prototype)
- 最简单的基于FFMPEG的音频编码器(PCM编码为AAC)
- Core Animation - 变换<一>
- CentOS下netstat + awk 查看tcp的网络连接状态
- c#关于日期的两个知识点
- CodeForces 622A Infinite Sequence