归并算法实现编程略显复杂
现实步骤分为分治与归并两部分。
分治
递归划分
直到单个元素为一组,这就是递归终止条件,即左指针等于右指针。
单元素一组,此时递归结束,递归函数返回则双元素为一组。
递归划分,划分线为 (右指针—左指针)/2+左指针。
循环终止条件:
if(left==right){
return;
}
划分线:
int mid=(right-left)/2+left;
递归划分:
// 递归划分
divide(a,left,mid);
divide(a,mid+1,right);
递归完毕,进行归并:
merge(a,left,mid,right);
划分完整代码:
void divide(int a[],int left,int right){
//递归终止条件,或者
/*
if(left!=right){
int mid=(right-left)/2+left;
// 递归划分
divide(a,left,mid);
divide(a,mid+1,right);
merge(a,left,mid,right);
}
*/
if(left==right){
return;
}
int mid=(right-left)/2+left;
// 递归划分
divide(a,left,mid);
divide(a,mid+1,right);
merge(a,left,mid,right);
}
归并部分:
需要的形参:
merge(int a[],int left,int mid,int right)
左右数组的起始指针:
int lp=left;
int rp=mid+1;
辅助数组与数组的起始索引:
int help[right-left+1];
int i=0;
循环检测,以从小到大的顺序,放入辅助数组:
while(lp<=mid&&rp<=right){
if(a[lp]<=a[rp]){
help[i]=a[lp];
lp++;
i++;
}else{
help[i]=a[rp];
rp++;
i++;
}
}
while(lp<=mid){
help[i]=a[lp];
i++;
lp++;
}
while(rp<=right){
help[i]=a[rp];
i++;
rp++;
}
辅助数组到原数组的输入:
i=0;
for(int k=left;k<=right;k++){
a[k]=help[i];
i++;
}
完整的归并代码:
void merge(int a[],int left,int mid,int right){
int lp=left;
int rp=mid+1;
int help[right-left+1];
int i=0;
while(lp<=mid&&rp<=right){
if(a[lp]<=a[rp]){
help[i]=a[lp];
lp++;
i++;
}else{
help[i]=a[rp];
rp++;
i++;
}
}
while(lp<=mid){
help[i]=a[lp];
i++;
lp++;
}
while(rp<=right){
help[i]=a[rp];
i++;
rp++;
}
i=0;
for(int k=left;k<=right;k++){
a[k]=help[i];
i++;
}
}
归并排序
Python
# -*- coding: utf-8 -*-
#归并算法分为划分归并两部分
# 其中,划分需要递归进行:递归则包含递归终止条件
def merge(li, left, mid, right):
# 左右指针
lp=left
rp=right
help=[right-left+1]
# help辅助列表的初始索引
i=0
while lp<=mid and rp<=right:
if li[lp]<=li[rp]:
# 值放入辅助数组
help[i]=li[lp]
# 指针变动
lp+=1
# 索引变动
i+=1
else:
help[i]=li[rp]
rp+=1
i+=1
# if else语句两侧都有i+=1,可以抽出来放入上一层while循环下
# 把左右两个子列表没有放入help的值,放入help
while lp<=mid:
help[i]=li[lp]
# 指针移位
lp+=1
#索引加一
i+=1
while rp<=right:
help[i]=li[rp]
# 指针移位
rp+=1
#索引加一
i+=1
# 索引归零
i=0
for j in range(left,right):
li[j]=help[i]
i+=1
def divide(li, left, right):
# 递归终止条件,单元素为一组
if left==right:
return
# if不成立,则进入递归
# 递归第一步:找寻划分线
mid=(right-left)/2+left
divide(li,left,mid)
divide(li,mid+1,right)
# 划分结束之后,进行归并
merge(li,left,mid,right)
if __name__ == '__main__':
li = [1, 2, 3, 6, 5, 4, 9, 8, 7, 0]
divide(li, 0, len(li) - 1)
print(li)