原地归并排序
2016-03-15 15:29
513 查看
原地归并排序相比于普通归并排序,不需要开拓额外空间就可进行两个有序数组的merge,故空间复杂度为O(1)
无论是原地归并排序还是普通归排序 最外层的递归形式都是统一的,如下
下面首先给出普通的merge 函数,需要申请辅助数组,现将待合并的两个数组都拷进去。
下面给出原地归并排序中merge函数的原理介绍
i 往后移动,找到第一个arr[i]>arr[j]的索引。如图找到30
j往后一栋,找到第一个arr[j]>arr[i]的索引。如图找到55
交换i到index-1和index到j的部分,采用局部数组循环移动的方法,通过三次数组逆序实现。交换后数组前半部分局部有序,之后重复进行此步骤即可实现两个有序数组的合并。
代码如下:
附上完整的测试代码
无论是原地归并排序还是普通归排序 最外层的递归形式都是统一的,如下
void MergeSort(int *arr,int low,int high) { if(low<high) { int mid=(low+high)/2; MergeSort(arr,low,mid); MergeSort(arr,mid+1,high); merge(arr,low,mid,high); } }
下面首先给出普通的merge 函数,需要申请辅助数组,现将待合并的两个数组都拷进去。
#define MAX_LEN 20 int B[MAX_LEN]; void merge(int *arr,int low,int mid,int high) { int i,j,k; for(k=low;k<=high;k++) B[k]=arr[k]; for(i=low,j=mid+1,k=low;i<=mid && j<=high;k++) { if(B[i]<B[j]) arr[k]=B[i++]; else arr[k]=B[j++]; } while(i<=mid) arr[k++]=B[i++]; while(j<=high) arr[k++]=B[j++]; }
下面给出原地归并排序中merge函数的原理介绍
i 往后移动,找到第一个arr[i]>arr[j]的索引。如图找到30
j往后一栋,找到第一个arr[j]>arr[i]的索引。如图找到55
交换i到index-1和index到j的部分,采用局部数组循环移动的方法,通过三次数组逆序实现。交换后数组前半部分局部有序,之后重复进行此步骤即可实现两个有序数组的合并。
代码如下:
void reverse(int *arr,int n) //逆序操作 { int i=0,j=n-1; while(i<j) { std::swap(arr[i],arr[j]); i++; j--; } } void exchange(int *arr,int n,int i) //将含有n个元素的数组循环左移i个位置 { reverse(arr,i); reverse(arr+i,n-i); reverse(arr,n); } void merge(int *arr,int begin,int mid,int end) { int i=begin,j=mid+1,k=end; while(i<j && j<=k) { int step=0; while(i<j && arr[i]<=arr[j]) i++; while(i<j && arr[j]<=arr[i]) { j++; step++; } exchange(arr+i,j-i,j-i-step); i+=step; } }
附上完整的测试代码
#include <algorithm>
#include <stdio.h>
#define MAX_LEN 20
int B[MAX_LEN];
void reverse(int *arr,int n) //逆序操作
{
int i=0,j=n-1;
while(i<j)
{
std::swap(arr[i],arr[j]);
i++;
j--;
}
}
void exchange(int *arr,int n,int i) //将含有n个元素的数组循环左移i个位置
{
reverse(arr,i);
reverse(arr+i,n-i);
reverse(arr,n);
}
//void merge(int *arr,int begin,int mid,int end)
//{
// int i=begin,j=mid+1,k=end;
// while(i<j && j<=k)
// {
// int step=0;
// while(i<j && arr[i]<=arr[j])
// i++;
// while(i<j && arr[j]<=arr[i])
// {
// j++;
// step++;
// }
//
// exchange(arr+i,j-i,j-i-step);
// i+=step;
// }
//}
//
void merge(int *arr,int low,int mid,int high)
{
int i,j
for(k=low;k<=high;k++)
B[k]=arr[k];
for(i=low,j=mid+1,k=low;i<=mid && j<=high;k++)
{
if(B[i]<B[j])
arr[k]=B[i++];
else
arr[k]=B[j++];
}
while(i<=mid) arr[k++]=B[i++];
while(j<=high) arr[k++]=B[j++];
}
void MergeSort(int *arr,int low,int high) { if(low<high) { int mid=(low+high)/2; MergeSort(arr,low,mid); MergeSort(arr,mid+1,high); merge(arr,low,mid,high); } }
int main(int argc, char const *argv[])
{
int arr[] = {6,4,3,1,7,8,2,9,5,0};
int testbrr[] = {10,30,50,60,80,20,25,55,65,73};
int len=sizeof(arr)/sizeof(arr[0]);
MergeSort(arr,0,len-1);
for (int i=0;i<len;i++)
printf("%d ",arr[i]);
return 0;
}
相关文章推荐
- 用VBScript写合并文本文件的脚本
- oracle列合并的实现方法
- 使用BAT一句话命令实现快速合并JS、CSS
- SQL 合并多行记录的方法总汇
- C#实现简单合并word文档的方法
- C#自适应合并文件的方法
- Node.js实现JS文件合并小工具
- GridView单元格合并
- 如何合并多个 .NET 程序集
- 使用UglifyJS合并/压缩JavaScript的方法
- 高性能WEB开发 JS、CSS的合并、压缩、缓存管理
- 多个js与css文件的合并方法详细说明
- 使用不同的方法结合/合并两个JS数组
- java实现归并排序算法
- 合并Excel工作薄中成绩表的VBA代码,非常适合教育一线的朋友
- 用js实现table单元格高宽调整,兼容合并单元格(兼容IE6、7、8、FF)实例
- C++实现八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序等
- C++实现自底向上的归并排序算法
- oracle实现多行合并的方法
- php分割合并两个字符串的函数实例