#include <iostream>
using namespace std;
void merge(int *a,int p,int q,int r)
{
//n1,n2多申请一个,每个数组最后一位用作哨兵
int n1=q-p+2;
int n2=r-q+1;
int i=0,j=0;
int *p1,*p2;
//为动态申请的数组分配内存,函数结束后还要释放,切记,两种申请动态内存的方式
//p1=(int *)malloc(n1*sizeof(int));
//p2=(int *)malloc(n2*sizeof(int));
p1=new int[n1];
p2=new int[n2];
//初始化两个数组,每个数组的最后一位用作哨兵,赋予最大值(很重要)
for(int i=0;i<n1-1;i++)
p1[i]=a[p+i];
p1[n1-1]=0x7fffffff;
for(int j=0;j<n2-1;j++)
p2[j]=a[q+j+1];
p2[n2-1]=0x7fffffff;
//不必担心哨兵会加入数组a,因为在加入之前for循环已经结束。
//如果不加入哨兵,有可能p1[i]已经全部添加到a[k]中,导致最后p1[i+1]不存在,然后无法判断,加入哨兵并赋予最大值可以继续判断,因此必须加哨兵并且赋予最大值。
for(int k=p;k<=r;k++)
{
if(p1[i]<=p2[j])
{
a[k]=p1[i];
i++;
}
else
{
a[k]=p2[j];
j++;
}
}
//释放动态申请的内存
//free(p1);
//free(p2);
delete [] p1;
delete [] p2;}
void merge_sort(int *a,int p,int r)
{
int q=0;
if(p<r)
{
q=(p+r)/2;
merge_sort(a,p,q);
merge_sort(a,q+1,r);
merge(a,p,q,r);
}
}
int main()
{
int a[10]={10,9,2,8,3,7,4,6,5,0};
merge_sort(a,0,9);
for(int i=0;i<10;i++)
cout<<a[i]<<" ";
cout<<endl;
}
原地归并排序
不需要额外分配内存空间:
#include<iostream>
using namespace std;
void reverse(int *arr , int n)
{
int i = 0 , j = n - 1;
while(i < j)
{
swap(arr[i] , arr[j]);
i++;
j--;
}
}
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 += step;
}
}
void mergeSort(int *arr , int left , int right)
{
if(left >= right)
return;
int mid = left + (right-left)/2;
mergeSort(arr , left , mid);
mergeSort(arr , mid+1 , right);
merge(arr , left , mid+1 , right);
}
int main()
{
int arr[] = {6,4,3,1,7,8,2,9,5,0};
int len = sizeof(arr) / sizeof(*arr);
mergeSort(arr , 0 , len-1);
for(int i = 0 ; i < len ; i++)
cout<<arr[i]<<" ";
cout<<endl;
return 0;
}