python数据结构与算法-13_高级排序算法-分治法

news2024/11/15 15:31:15

分治法 (Divide and Conquer)

很多有用的算法结构上是递归的,为了解决一个特定问题,算法一次或者多次递归调用其自身以解决若干子问题。
这些算法典型地遵循分治法的思想:将原问题分解为几个规模较小但是类似于原问题的子问题,递归求解这些子问题,
然后再合并这些问题的解来建立原问题的解。

分治法在每层递归时有三个步骤:

  • 分解原问题为若干子问题,这些子问题是原问题的规模最小的实例
  • 解决这些子问题,递归地求解这些子问题。当子问题的规模足够小,就可以直接求解
  • 合并这些子问题的解成原问题的解

归并排序

现在我们就来看下归并排序是是如何利用分治法解决问题的。

  • 分解:将待排序的 n 个元素分成各包含 n/2 个元素的子序列
  • 解决:使用归并排序递归排序两个子序列
  • 合并:合并两个已经排序的子序列以产生已排序的答案

考虑我们排序这个数组:[10,23,51,18,4,31,13,5] ,我们递归地将数组进行分解

在这里插入图片描述

当数组被完全分隔成只有单个元素的数组时,我们需要把它们合并回去,每次两两合并成一个有序的序列。

在这里插入图片描述

用递归代码来描述这个问题:

def merge_sort(seq):
    if len(seq) <= 1:   # 只有一个元素是递归出口
        return seq
    else:
        mid = int(len(seq)/2)
        left_half = merge_sort(seq[:mid])
        right_half = merge_sort(seq[mid:])

        # 合并两个有序的数组
        new_seq = merge_sorted_list(left_half, right_half)
        return new_seq

注意我们这里有一个函数没实现,就是如何合并两个有序数组 merge_sorted_list。其实你在纸上画一画,
合并两个有序数组并不难实现。

在这里插入图片描述

在这里插入图片描述

def merge_sorted_list(sorted_a, sorted_b):
    """ 合并两个有序序列,返回一个新的有序序列

    :param sorted_a:
    :param sorted_b:
    """
    length_a, length_b = len(sorted_a), len(sorted_b)
    a = b = 0
    new_sorted_seq = list()

    while a < length_a and b < length_b:
        if sorted_a[a] < sorted_b[b]:
            new_sorted_seq.append(sorted_a[a])
            a += 1
        else:
            new_sorted_seq.append(sorted_b[b])
            b += 1

    # 最后别忘记把多余的都放到有序数组里
    if a < length_a:
        new_sorted_seq.extend(sorted_a[a:])
    else:
        new_sorted_seq.extend(sorted_b[b:])

    return new_sorted_seq

这样就实现了归并排序,并且你会发现它返回一个新的数组而不是修改原有数组。

时间复杂度

我们来简单看下它归并排序的时间复杂度,假设排序 n 个数字时间复杂度是 T(n),这里为了方便假设 n 是 2 的幂

\begin{align}
T(n)= \begin{cases} c, & \text {if n n n = 1} \ 2T(n/2)+cn, & \text{if n n n > 1} \end{cases}
\end{align}

在这里插入图片描述

总的代价是 c n l g ( n ) + c n cnlg(n)+cn cnlg(n)+cn ,忽略常数项可以认为是 O(nlg(n))。如果这个图看不懂,我们自己求解下也不难,首先我们简化一下,
把常数系数当成 1,得到以下递归式:

\begin{align}
T(n)= \begin{cases} 1, & \text {if n n n = 1} \ 2T(n/2)+n, & \text{if n n n > 1} \end{cases}
\end{align}

在这里插入图片描述

思考题

  • 请你完成归并排序的单元测试
  • 这里实现的归并排序是 inplace 的吗?
  • 归并排序是稳定的吗?稳定指的是排序前后相同大小的数字依然保持相对顺序。

延伸阅读

  • 《算法导论》第 2 章和第 4 章,你需要了解下『主定理』,以及如何求解形如 T ( n ) = a T ( n / b ) + f ( n ) T(n)=aT(n/b) + f(n) T(n)=aT(n/b)+f(n) 的递归式复杂度
  • 了解算法导论上递归式的三种求解方法:代入法,递归树法,主方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1237293.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C盘变红怎么办?一个快速解决C盘快满的方法

前情提要 通常解决C盘快满的方法是&#xff1a; 找到C盘—右击选择“属性”—选择“详细信息”—卸载不常用的软件或者清除临时文件 缺点&#xff1a;成效甚微 今日重点 1.背景知识&#xff1a;微信是我们日常工作和生活都离不开的工具&#xff0c;我们每天使用微信会产生大量…

系列四、ThreadLocal的工作原理

一、内存结构图 二、工作原理 &#xff08;1&#xff09;Thread有一个类型为ThreadLocal.ThreadLocalMap threadLocals 的实例变量&#xff0c;即每个线程都有一个属于自己的ThreadLocalMap&#xff1b; &#xff08;2&#xff09;ThreadLocalMap内部维护着Entry数组&#xff0…

用合成数据训练语义分割模型【裂缝检测】

最近&#xff0c;我们推出了合成裂缝分割数据集&#xff0c;在本文中&#xff0c;我们将深入探讨应用于合成数据生成过程的改进和启发式方法。 阅读完这篇文章后&#xff0c;你将了解我们如何设法创建一个数据集&#xff0c;该数据集可以像使用真实数据一样高效地训练模型。 在…

干货分享:本地生活服务商入驻申请需要哪些条件?附更快捷的方法!

在数字化时代&#xff0c;本地服务市场已经成为各大平台争夺的重要阵地。抖音不仅在短视频市场占有一席之地&#xff0c;同时也在如火如荼的开发着本地服务市场&#xff0c;相继支付宝、视频号也推出了本地生活服务商模式。本文将介绍抖音本地生活服务商的申请条件&#xff0c;…

Django ORM 执行复杂查询的技术与实践

概要 Django ORM&#xff08;Object-Relational Mapping&#xff09;是 Django 框架的核心组件之一&#xff0c;提供了一种高效、直观的方式来处理数据库操作。尽管简单查询在 Django ORM 中相对容易实现&#xff0c;但在面对复杂的数据请求时&#xff0c;需要更深入的了解和技…

申银万国期货通过ZStack Cube信创超融合一体机打造金融信创平台

信创是数字中国建设的重要组成部分&#xff0c;也是数字经济发展的关键推动力量。作为云基础软件企业&#xff0c;云轴科技ZStack产品矩阵全面覆盖数据中心云基础设施&#xff0c;ZStack信创云首批通过可信云《一云多芯IaaS平台能力要求》先进级&#xff0c;是其中唯一兼容四种…

HUAWEI华为MateBook X Pro 2022 12代酷睿版(MRGF-16)笔记本电脑原装出厂Windows11系统工厂模式含F10还原

链接&#xff1a;https://pan.baidu.com/s/1ZI5mR6SOgFzMljbMym7u3A?pwdl2cu 提取码&#xff1a;l2cu 华为原厂Windows11系统工厂包&#xff0c;带F10一键智能还原恢复功能。 自带指纹、面部识别、声卡、网卡、显卡、蓝牙等所有驱动、出厂主题壁纸、Office办公软件、华为…

早安,朋友!每天问候语祝你天天好心情,事事都顺意

1、今天的风儿轻柔无比&#xff0c;今天的花儿香飘万里&#xff1b;今天的鸟儿十分欢喜&#xff0c;今天的云儿满载笑意&#xff1b;今天的事儿万分顺利&#xff0c;今天的人儿如此甜蜜&#xff0c;所有美好的一切同我的早安连在一起&#xff0c;祝你天天好心情&#xff0c;事事…

【C++ 学习 ㊴】- 详解 C++ 的 I/O 流

目录 一、C 的 I/O 流 二、C 的标准 I/O 流 三、C 的文件 I/O 流 一、C 的 I/O 流 C 语言有一套完成数据读写&#xff08;I/O&#xff09;的解决方案&#xff1a; 使用 scanf()、gets() 等函数从键盘读取数据&#xff0c;使用 printf()、puts() 等函数向屏幕输出数据&#…

未履行数据保护义务造成数据泄露,某大药房被罚110万

近日&#xff0c;温州网安部门发现温州某大药房销售数据在暗网售卖&#xff0c;侵犯了公民个人信息&#xff1b;同时发现该大药房未履行数据保护义务&#xff0c;造成了数据泄露&#xff0c;由此对售卖数据的大药房数据分析师采取刑事强制措施&#xff0c;并对该公司处罚款110万…

快速选择算法

前言 本文将会向你介绍什么是快速选择算法&#xff0c;&#xff08;用两道例题来讲解&#xff09;算法原理是什么 引入 快速选择算法和快速排序算法都是基于分治思想的算法&#xff0c;它们的基本原理是类似的&#xff0c;都是通过将数组分成两部分&#xff0c;然后递归地处理…

手写promis(2)-- 链式编程篇

目录 链式编程 处理异常 和普通内容 链式编程---处理返回promise 链式编程---处理重复引用 链式编程--rejected 链式编程--处理padding状态 链式编程 处理异常 和普通内容 1.返回promise实例&#xff1a;在原本then方法里边创建新promise2.获取返回值&#xff1a;把原本…

jQuery实现横版手风琴效果

一、实现效果 当鼠标滑过方块的时候&#xff0c;方块的状态就会发生如下图所示的变化&#xff0c;同理当鼠标滑到其他的方块也会发生同样的效果&#xff0c;不仅大小会改变同时方块的颜色也会跟着发生变化&#xff1a; 二、代码实现 <!DOCTYPE html> <html><h…

如何通过提升客户体验带来更大的增长、更好的客户留存率?

客户期望的转变 在一个日益数字化的世界里&#xff0c;有必要采取以客户为中心的思维方式。因为客户与企业互动的方式有很多是在数字空间发生的&#xff0c;客户的需求和模式已经转变。 这种情况已经酝酿了几年&#xff0c;但在2020年才打开闸门。随着疫情的爆发&#xff0c;企…

java ssh 二手车交易管理系统eclipse开发mysql数据库MVC模式java编程网页设计

一、源码特点 JSP ssh 二手车交易管理系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用 B/S模式开发。开发环境为TOMCAT…

柯桥考级日语学校,日语听力如何拿满分

今天&#xff0c;来分析一下能力考听力中的五道听力题的题型和解题技巧。 首先在N1和N2中&#xff0c;听力题型是一样的。 第一大题「課題理解」 第二大题「ポイント理解」 第三大题「概要理解」 第四大题叫做「即時応答」 第五大题叫做「統合理解」 名字不同&#xff0c;考点和…

秋招如何准备?有什么建议?

秋招&#xff0c;是毕业生最好的求职渠道&#xff0c;没有之一。尽管还有春招&#xff0c;社招......都不如秋招重要&#xff0c;因为秋招的机会更多..... 如何准备秋招&#xff1f; 1、简历很重要 一个好的简历&#xff0c;就是敲门砖&#xff0c;这是你跟企业HR的第一次亲…

python -opencv形态学操作

python -opencv形态学操作 1.服饰和膨胀 1.服饰和膨胀 opencv 腐蚀通过cv2.erode实现&#xff0c;膨胀通过cv2.dilate实现&#xff0c;看一下下面代码&#xff1a; from ctypes.wintypes import SIZE from multiprocessing.pool import IMapUnorderedIterator import cv2 i…

20231122给RK3399的挖掘机开发板适配Android12

20231122给RK3399的挖掘机开发板适配Android12 2023/11/22 9:30 主要步骤&#xff1a; rootrootrootroot-X99-Turbo:~$ tar --use-compress-programpigz -xvpf rk356x_android12_220722.tgz rootrootrootroot-X99-Turbo:~$ cd rk_android12_220722/ rootrootrootroot-X99-Tur…