【分治】归并、快排 思路 python代码详解

一,分治

        分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。

         如果这些子问题还较大,难以解决,可以再把它们分成几个更小的子问题,以此类推,直至可以直接求出解为止。这就是分治策略的基本思想。

        即一种分目标完成程序算法,简单问题可用二分法完成。

二,生活案例

        1,找出伪币

        16枚硬币,不同面值,有可能有一枚假币,假币比真币轻。有一架天平,用最少称量次数确定有没有假币,若有的话,假币是哪一枚?

        分治策略思路:将同面值硬币分类,称量。结果为无假币或者确定假币的一面值 。再均分,称量。

三,解题步骤

(1)分解。将要解决的问题划分成若干规模较小的同类问题;

(2)求解。当子问题划分得足够小时,用较简单的方法解决;

(3)合并。按原问题的要求,将子问题的解逐层合并构成原问题的解。

 

四,归并排序

手动演算

 

 代码实现

def Merge(s1, s2, s):
    i = j = 0  # 两段数组放在起始位置的指针
    while (i + j) < len(s):  # 双指针长度小于该s总长度就一直进行
        if j == len(s2) or (i < len(s1) and s1[i] < s2[j]):  # 如果i指针指向数小于j指针指向数且i没走到头,或者j走到头了
            s[j + i] = s1[i]  # 那么将s1数赋给s
            i += 1  # i往后走一位

        else:  # 其他情况(i走到头了,或者j没走到头情况下j指向的数小于i指向的数)
            s[i + j] = s2[j]  # s2数赋给s
            j += 1  # j往后走一位


def Merge_Sort(s):  # 将数组拆分
    n = len(s)
    if n < 2:  # 数组长度是1时,不拆分直接返回
        return
    mid = n // 2
    s1 = s[0:mid]  # 将数组拆分为两段
    s2 = s[mid:n]
    Merge_Sort(s1)  # 递归,将两段数组再分别进行拆分
    Merge_Sort(s2)
    Merge(s1, s2, s)  # 将拆分好的数组组合


if __name__ == "__main__":
    s = [1, 4, 2, 9, 6, 77]
    Merge_Sort(s)
    print(s)  # 输出

五,快速排序

手动演算

 代码

def Quick_Sort(a, start, end):
    if start >= end:  # 退出递归的条件
        return
    pivot = a[start]    # 设起始基准元素
    left = start    #左指针
    right = end     #右指针
    while left < right:     #右指针大于基准数条件向右扫描
        while a[right] > pivot:
            right -= 1
        a[left] = a[right]      #右指针小于基准数和左指针数交换
        while a[left] < pivot:      #左指针小于基准数向左扫描
            left += 1
        a[right] = a[left]      #左指针大于基准数和右指针数交换
    a[right] = pivot    #当指针相遇时,基准数填入指针所指的空缺位置中
    Quick_Sort(a, start, left - 1)      #将基准数之前的数再排列
    Quick_Sort(a, left + 1, end)        #将基准数之后的数再排列


if __name__ == "__main__":      #告诉程序在main中进行
    a = [5, 4, 7, 2, 9, 1, 77]
    Quick_Sort(a, 0, len(a) - 1)
    print(a)

      

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值