原地归并排序
不需要辅助数组即可归并。
关键在于merge这个函数。两段递增的子数组arr[begin…mid-1]和arr[mid…end],i=begin,j=mid,k=end
i往后移动,找到第一个arr[i]>arr[j]的索引
j往后移动,再找第一个arr[j]>arr[i]的索引
然后我们将i到mid的部分和mid到j-1的部分对调,较小的部分就调到前面去了,然后从后面的部分与j到k的部分又是两个递增的子数组,继续迭代即可。
#include <iostream> using namespace std; //交换两个数 void swap(int *a,int *b) { int temp=*a; *a=*b; *b=temp; } //将长度为n的数组逆序 void reverse(int *arr,int n) { int i=0,j=n-1; while(i<j) { swap(arr[i],arr[j]); i++; j--; } } //将数组向左循环移位i个位置 void exchange(int *arr,int n,int 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,k=end; while(i<j && j<=k) { int step=0; while(i<j && arr[i]<=arr[j]) ++i; while(j<=k && arr[j]<=arr[i]) { ++j; ++step; } exchange(arr+i,j-i,j-i-step); i=i+step; } } void MergeSort(int *arr,int l,int r) { if(l<r) { int mid=(l+r)/2; MergeSort(arr,l,mid); MergeSort(arr,mid+1,r); merge(arr,l,mid+1,r); } } int main() { int arr[]={6,4,3,1,7,8,2,9,5,0}; int len=sizeof(arr)/sizeof(arr[0]); MergeSort(arr,0,len-1); for(int i=0;i<len;++i) cout <<arr[i]<<" "; cout <<endl; return 0; }