第一部分 2.3分治算法

分治算法是经典算法之一,其“分而治之”的思想在大多数有名的算法中都有应用。大致说下分治算法的基本原理吧:

  1. 将大规模问题每次通过分解成小问题进行处理。
  2. 其次,将分解出的这些子问题逐个解决。
  3. 最后,将已解的子问题合并,最终得出原问题的解

这里说的很简单,具体可参考博客

(129条消息) 分治法(python)_暗物质鬼的博客-CSDN博客_分治算法pythonhttps://blog.csdn.net/qq_48959845/article/details/121302246

本次根据书中的分治算法伪代码与一些大佬参考代码,利用python来实现。

Python 算法入门教程 - 分治算法介绍 - IT学院 - 中国软件协会智能应用服务分会 (itxueyuan.com) 1.参考原书代码

由于分治算法最终的步骤是实现排序后的数组,所以该部分是先实现两个有序数组的合并。

书中的伪代码貌似不太好理解,没关系,可以看下某位大佬画的图片更好理解。参考来源 Python 算法入门教程 - 分治算法介绍 - IT学院 - 中国软件协会智能应用服务分会 (itxueyuan.com)

由于实现过程比较繁琐,可以将整个思路拆分成两部分。

部分1:实现有两个有序结列表的合并

部分2:实现一个无需列表的递归划分,和排序

最后,在部分2中调用部分1函数,即可将众多子数组不断合并

下方代码参考:Python 算法入门教程 - 分治算法介绍 - IT学院 - 中国软件协会智能应用服务分会 (itxueyuan.com)

部分1 

# -*- coding: utf-8 -*-
"""
Created on Fri Aug  5 15:30:34 2022
Content: 分治算法:实现有序两数组的合并排序
         分治算法基本原理:
         1> 对一个数组进行分解,分解成2个或多个
         2> 计算分解后的子数组
         3> 合并每个子数组的排序结果
         4> 得到最终结果
@author: xiaofang
"""

def merge_sorted_list(nums1, nums2):
    """
    合并有序数组
    """
    
    #创建1*n的初始化数组
    nums = [0] * (len(nums1) + len(nums2))
    #初始化索引
    id, id1, id2 = 0, 0, 0
    #>1 确保两数组都没走完。
    #当人一个数组和索引超出后数组自身长度,即数组已完成比较,终止
    while id1 < len(nums1) and id2 <len(nums2):
        #较两数组第一位数,并执行存储
        while id1 < len(nums1) and id2 <len(nums2) and nums1[id1] <= nums2[id2]:
            nums[id] = nums1[id1] 
            id += 1
            id1 += 1
        while id1 < len(nums1) and id2 <len(nums2) and nums1[id1] > nums2[id2]:
            nums[id] = nums2[id2] 
            id += 1
            id2 += 1
    #>2 将没走完的数组剩余部分放输出数组后面
    #任何情况都有先走完的数组,后走的数组至少剩余一个元素       
    if id1 !=len(nums1):
        nums[id: ] = nums1[id1: ]
    if id2 != len(nums2):
        nums[id:] = nums2[id2: ]
    
    return nums

nums1 = [1, 5, 21, 89, 90]
nums2 = [6, 12, 21, 65, 230,]

print(merge_sorted_list(nums1, nums2))

部分2

def merge_sort(nums):
    """
    对一列无序的数组进行划,每次划分成2等份,并且进行排序
    """
    if len(nums) == 0 or len(nums) == 1:
        return nums
    if len(nums) == 2:
        if nums[0] > nums[1]:
            nums[0], nums[1] = nums[1], nums[0]
        return nums
    
    #递归公式,将列表分成两份,递归排序下去
    half = len(nums) // 2
    nums1 = merge_sort(nums[:half])
    nums1 = merge_sort(nums[half: ])
    
    return merge_sorted_list(nums1, nums2)

输出 

nums = [1, 5, 2, 4, 45, 2, 535, 73]
print(merge_sort(nums)) # 输出[1, 2, 2, 4, 5, 45, 73, 535]

总结

分治算法的理论核心,正如其名一样,分而治之。先将一列无序列表递归划分足够小的列表(本文是2元素列表),在对子列表进行排序,最后调用合并算法合并结果。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值