归并排序(Merge Sort)
一.原理
归并排序是采用分治法建立在一系列归并操作上的排序算法。
大致思路为将一个序列分解为多个最小的子序列,再不断向上合并合并两个有序子序列,直到序列规模和原序列一样大。
归并排序分治过程
二.代码实现
#include<iostream>
using namespace std;
void MergeArray(int *a,int left,int mid,int right,int *temp)
{
int k=0;
int i=left,j=mid+1;
while(i<=mid && j<=right)
{
if(a[i]<=a[j])
{
temp[k++]=a[i++];
}
else{
temp[k++]=a[j++];
}
}
while(i<=mid)
{
temp[k++]=a[i++];
}
while(j<=right)
{
temp[k++]=a[j++];
}
for(int i=0;i<k;i++)
{
a[left+i]=temp[i];
}
}
void merge(int *a,int left,int right,int *temp)
{
int mid;
if(left<right)
{
mid=(left+right)/2;
merge(a,left,mid,temp);
merge(a,mid+1,right,temp);
MergeArray(a,left,mid,right,temp);
}
}
void MergeSort(int *array,int length)
{
int *temp=new int[length];
int left=0;
merge(array,left,length-1,temp);
delete[] temp;
}
void Print(int *a,int length)
{
for(int i=0;i<length;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
int main()
{
int *array;
int n;
cout<<"How many elements do you want ? ";
cin>>n;
array=new int[n];
cout<<"Please enter the elements:";
for(int i=0;i<n;i++)
{
cin>>array[i];
}
MergeSort(array,n);
Print(array,n);
return 0;
}
这里重点需要注意合并子序列的操作中,将temp中的元素复制到原序列中时,原序列的下标并不是从0开始,因为每一次归并,子序列在原序列中的位置是不同的,所以下标应该为left+i,子序列在原序列中的对应位置是不变的。
三.算法复杂度
归并排序的效率是比较高的,设序列长为N,将序列分开成小数列一共要logN步,每步都是一个合并有序序列的过程,时间复杂度可以记为O(N),故一共为O(N*logN)。因为归并排序每次都是在相邻的数据中进行操作,所以归并排序在O(N*logN)的几种排序方法(快速排序,归并排序,希尔排序,堆排序)也是效率比较高的,并且是十分稳定的,没有最坏与最好情况。