本文将介绍归并排序算法的基本思想及其C++和Python的代码实现。
- 归并排序基本思想:
首先将待排序数列两两分组,将排序好的两个序列归并到中间数组中,依次类推,直到归并完整个待排序数列。 - C++实现:
//打印排序结果函数
void Print(int a[],int n,int i=0)
{
//cout<<i<<endl;
cout<<"排序后的结果为:"<<endl;
for(int i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
}
//归并排序
//合并两子序列函数,其中a为待排序序列,rf为中间序列,i为第一个子序列中第一个元素下标,
//m为第一个子序列最后一个元素的下标,n为第二个子序列最后一个元素的下标
void Merge(int *a,int *rf,int i,int m,int n)
{
int k=i,j=m+1; //k为中间序列下标,初值与i相同,j为第二个子序列第一个元素的下标
//对两个子序列中的元素遍历,将两个子序列中较小的元素放入中间序列rf的前面,只要遍历完一个子序列便结束
while(i<=m && j<=n)
{
if(a[i]<=a[j])
rf[k++]=a[i++];
else
rf[k++]=a[j++];
}
//将两个子序列中的剩余元素放入rf中
while(i<=m) rf[k++]=a[i++];
while(j<=n) rf[k++]=a[j++];
Print(rf,n+1); //打印中间结果
}
void MergeSort(int *a,int *rf,int n)
{
int *q=a; //将*a保存起来
int len=1; //初始子序列长度
int *temp; //数组交换中间变量
while(len<n)
{
int i=0; //每一趟归并时,数组第一个元素下标
int s=len; //单个子序列长度
len=2*s; //子序列总长度
while(i+len<n)
{
//i为第一个子序列第一个元素下标;
//i+s-1为第一个子序列最后一个元素下标;i+len-1为第二个子序列最后一个元素下标
Merge(q,rf,i,i+s-1,i+len-1);
//更新i值,进行下一次归并
i=i+len;
}
if(i+s<=n) //对于归并组数为奇数的情形,归并时会有剩余子序列,将其并入前一个归并序列中
Merge(q,rf,i,i+s-1,n-1);
temp=q;q=rf;rf=temp; //交换,对rf进行归并排序
}
}
3.Python实现:
'''输出排序结果函数'''
def Print(ddata):
n=len(ddata)
for i in range(n):
print ddata[i], #其中","为了不让其输出默认的换行符
'''归并排序'''
def Merge(data,rf,i,m,n):
j=m+1;k=i #两个待归并数组的初始下标
'''将两待归并数组中的较小元素依次赋给rf'''
while(i<=m and j<=n): #两个待归并数组长度
if data[i]<=data[j]:
rf[k]=int(data[i])
i+=1;k+=1
else:
rf[k] =int(data[j])
j+=1;k+=1
'''将两归并数组中的剩余元素赋给rf'''
while(i<=m):
rf[k] = int(data[i])
i+=1;k+=1
while(j<=n):
rf[k] = int(data[j])
j+=1;k+=1
def MergeSort(data,n):
rf=zeros(n)
len=1
while(len<n):
i=0
s=len
len=2*s
'''对两两成对的数组归并'''
while(i+len<n):
Merge(data,rf,i,i+s-1,i+len-1)
i=i+len
'''对单出的数组归并'''
if(i+s<=n):
Merge(data,rf,i,i+s-1,n-1)
data,rf=rf,data
print '排序结果为:'
Print(data)