归并

归并算法实现编程略显复杂

现实步骤分为分治与归并两部分。

分治 

递归划分

直到单个元素为一组,这就是递归终止条件,即左指针等于右指针。

单元素一组,此时递归结束,递归函数返回则双元素为一组。

递归划分,划分线为     (右指针—左指针)/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)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值