NB三人组(堆排序,归并排序,快速排序)(数据结构课设篇2,python版)(排序综合)

本篇博客主要详细讲解一下NB三人组排序,为什么叫NB三人组呢?因为他们的时间复杂度都为O(n log n)。第一篇博客讲解的是LowB三人组(冒泡排序,插入排序,选择排序),第三篇博客会讲解其他排序(基数排序,希尔排序和桶排序)

random和time库的用法在第一篇冒泡排序里讲解过。数据结构课设实验内容也在第一篇博客中。

概念:

堆排序是一种利用堆这种数据结构来进行排序的算法,它的时间复杂度为O(n log n),具有很好的性能。它的主要特点是不稳定排序,且不适合小数据集。

归并排序是一种分治算法,它将待排序的序列分成若干个子序列,分别进行排序,然后将已排序的子序列合并成一个有序序列。它的时间复杂度也为O(n log n),具有稳定性和适用于大数据集的特点。

快速排序是一种分治算法,它通过选取一个基准元素,将序列分成两部分,分别对两部分进行排序,然后递归地对子序列进行排序。它的时间复杂度为O(n log n),具有不稳定性和适用于大数据集的特点。

堆排序:

首先讲解一下堆排序的过程,这里是构造大根堆,首先对数组进行建堆操作,建好堆以后对堆进行堆排序,之后再建堆,再排序 往复操作直到所有排序完成。

堆排序比较复杂,难度在于理解上。
这里就不详细讲解建堆过程,步骤过多。
如图:
在这里插入图片描述

代码及详细注释:

import random
import time
def sift(li, low, high):'''堆调整函数:param li: 列表:param low: 堆的根节点位置:param high: 堆的最后一个元素的位置:return:'''i = low  # i最开始指向根节点j = 2*i + 1  # j开始时左孩子 因为这里的下标实际是数组的下标所以左孩子不是2*i,tmp = li[low]  # 把堆顶存起来while j <= high:  # 只要j位置有数if j + 1 <= high and li[j+1] > li[j]:  # 如果有右孩子并且右孩子比左孩子大j = j + 1  # j指向右孩子if li[j] > tmp:li[i] = li[j]i = j      # 往下看一层j = i*2 + 1else:          # tmp更大,把tmp放到i的位置上li[i] = tmp   # 把tmp放在某一级领导位置上breakelse:li[i] = tmp     # 把tmp放在叶子节点上def heap_sort(li):n = len(li)for i in range((n-2)//2, -1, -1):# i表示建堆的时候调整的部分的根的小标sift(li, i, n-1)# 建堆完成了for i in range(n-1, -1, -1):# i 指向当前堆的最后一个元素li[0], li[i] = li[i], li[0]sift(li, 0, i-1)  # i-1是新的highli = [random.randint(1, 100000000) for i in range(10000)]
start = time.time()
print(li)
heap_sort(li)
print(li)
end = time.time()
print('运行时间:%s Seconds'%(end-start))

运行结果:在这里插入图片描述

归并排序:

归并排序用的是分治法,把一个大问题化解为k个中问题,每个中问题再化解为k个小问题,直至问题化为最小可解的问题。对这些问题求解,再不断地合并结果,直至合并完毕。
如图:
在这里插入图片描述

代码及详细注释:

import random
import time
def merge(li, low, mid, high):'''归并函数,用来合并两个有序序列:param li: 列表:param low: 左边有序序列的起始位置:param mid: 左边有序序列的结束位置:param high: 右边有序序列的结束位置:return:'''i = lowj = mid + 1itmp = []while i <= mid and j <= high:  # 只要左右两边都有数if li[i] < li[j]:itmp.append(li[i])i += 1else:itmp.append(li[j])j += 1# while执行完,肯定有一部分没数了while i <= mid:itmp.append(li[i])i += 1while j <= high:itmp.append(li[j])j += 1li[low:high + 1] = itmp  # 将合并后的有序序列放回原列表def merge_sort(li, low, high):'''归并排序函数:param li: 列表:param low: 起始位置:param high: 结束位置:return:'''if low < high:mid = (low + high) // 2  # 至少有两个元素,递归merge_sort(li, low, mid)  # 对左半部分进行归并排序merge_sort(li, mid + 1, high)  # 对右半部分进行归并排序merge(li, low, mid, high)  # 合并两个有序序列li = [random.randint(1, 100000000) for i in range(10000)]
start = time.time()
print(li)
merge_sort(li, 0, len(li) - 1)
print(li)
end = time.time()
print('运行时间:%s Seconds'%(end-start))

归并排序比较好写但不好理解,这里跟大家讲一下具体理解,
def merge()里代码的含义是一次归并的过程,比如 [2,4,5,7,1,3,6,8] 该数组从mid(索引3)开始左右两边有序,现在合并成一个有序数组,i 指向元素2,j指向元素1,两者比较,小的数(1)进新数组,然后指针j 后移一位,继续跟i指针指向的元素比较,小的进数组,一直重复,直到一边无数可比为止,然后把另一边的剩余未比较的数组全部入新数组。
def merge_sort()函数作用是递归分解原数组,分解到只剩一个元素,最后再调用def merge()函数进行合并

运行结果:

在这里插入图片描述

快速排序:

快速排序是一种基于分治思想的排序算法,其过程可以描述如下:

  1. 选择一个基准元素(通常是数组中的第一个元素)。
  2. 将数组中小于基准元素的元素移动到基准元素的左边,大于基准元素的元素移动到右边,基准元素则位于最终排序位置。
  3. 对基准元素左右两边的子数组分别进行快速排序,直到子数组长度为1或0。
    递归地重复步骤2和步骤3,直到整个数组有序。

如图:
在这里插入图片描述
在这里插入图片描述

代码及详细注释:

import random
import time
def partition(li, left, right):'''划分函数,用于将列表分成两部分并返回中间位置:param li: 列表:param left: 左边界:param right: 右边界:return: 中间位置'''tmp = li[left]while left < right:while left < right and li[right] >= tmp:  # 从右面找比tmp小的数right -= 1                            # 往左走一步else:li[left] = li[right]                  # 把右边的值写到左边空位上while left < right and li[left] <= tmp:   # 从左边找比tmp大的数left += 1else:li[right] = li[left]                  # 把左边的值写到右边空位上li[left] = tmp                                # 把tmp归位return leftdef quick_sort(li, left, right):'''快速排序函数:param li: 列表:param left: 起始位置:param right: 结束位置:return:'''if left < right:  # 至少两个元素mid = partition(li, left, right)  # 划分并获取中间位置quick_sort(li, left, mid - 1)  # 对左半部分进行快速排序quick_sort(li, mid + 1, right)  # 对右半部分进行快速排序li = [random.randint(1, 100000000) for i in range(10000)]
start = time.time()
print(li)
quick_sort(li, 0, len(li) - 1)
print(li)
end = time.time()
print('运行时间:%s Seconds'%(end-start))

快排要用双指针法,两个指针来遍历数组进行比较,直到指针相遇。递归调用的思想跟归并差不多

运行结果:

在这里插入图片描述

总结:

之前的LowB三人组是看代码里的注释就可以理解,没有必要讲。而NB三人组的每趟排序的详细过程步骤篇幅太长,不太好讲,也不好找图片,只能粗略带大家过一遍。

通过运行时间可以明显看出NB三人组的运行效率比LowB三人组快很多,不过NB三人组的算法思想稍微有点难理解,如果理解了代码还是较容易实现,我认为难点在递归调用的理解上面,每一趟的排序实现还是容易写出来的。排序综合还剩下最后一篇其他排序的讲解就结束了。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1.3进制,码(8421),化简规则、卡诺图化简、性质,触发器(转换与设计、应用),电路图,电路设计

十进制与原码、反码、补码之间的转换 正数的原码、反码、补码相同&#xff0c;符号位为0 负数的原码为、符号位1&#xff0c;二进制数 反码&#xff0c;符号位不变、其它取反&#xff0c; 补码为&#xff1a;反码最低有效位1 运算 卡诺图化简 奇偶校验码 检查1的个数&…

机器学习--回归算法

&#x1f333;&#x1f333;&#x1f333;小谈&#xff1a;一直想整理机器学习的相关笔记&#xff0c;但是一直在推脱&#xff0c;今天发现知识快忘却了&#xff08;虽然学的也不是那么深&#xff09;&#xff0c;但还是浅浅整理一下吧&#xff0c;便于以后重新学习。 &#x1…

使用 Kafka 和 CDC 将数据从 MongoDB Atlas 流式传输到 SingleStore Kai

SingleStore 提供了变更数据捕获 (CDC) 解决方案&#xff0c;可将数据从 MongoDB 流式传输到 SingleStore Kai。在本文中&#xff0c;我们将了解如何将 Apache Kafka 代理连接到 MongoDB Atlas&#xff0c;然后使用 CDC 解决方案将数据从 MongoDB Atlas 流式传输到 SingleStore…

第11章 GUI Page462~476 步骤二十三 步骤二十四 Undo/Redo ②“添加操作”支持“Undo/Redo”

工程二 1.为AddAction类添加Undo() Redo() GetName()成员函数 2.实现AddAction类的Undo() Redo()函数 3.运行效果&#xff0c;但是日志窗口没有记录 原因&#xff1a;AddAction(EditAction* newAction)函数没有实现&#xff0c;另外参数是EditAction类型 所以我们还需要在基…

【源码预备】Calcite基础知识与概念:关系代数概念、查询优化、sql关键字执行顺序以及calcite基础概念

文章目录 一. 关系代数的基本知识二. 查询优化三. SQL语句的解析顺序1. FROM2. WHERE3. GROUP BY4. HAVING5. SELECT 四. Apache Calcite中的基本概念1. Adapter2. Calcite中的关系表达式2.1. 关系表达式例子2.2. 源码底层结构 3. Calcite的优化规则4. Calcite的Trait--算子物理…

初识大数据,一文掌握大数据必备知识文集(12)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

C++上位软件通过Snap7开源库访问西门子S7-1200/S7-1500数据块的方法

前言 本人一直从事C上位软件开发工作较多&#xff0c;在之前的项目中通过C访问西门子PLC S7-200/S7-1200/S7-1500并进行数据交互的应用中一直使用的是ModbusTCP/ModbusRTU协议进行。Modbus上位开源库采用的LibModbus。经过实际应用发现Modbus开源库单次发送和接受的数据不能超过…

web3d-three.js场景设计器-TransformControls模型控制器

场景设计器-TransformControls 控制器 该控制器可以指定模型进入可控制模式-如图有三种控制方式 translate --移动模式 rotate -- 旋转模式 scale -- 缩放模式 方便布局过程中快捷对模型进行摆放操作。 引入方式 import { TransformControls } from three/examples/jsm/…

数据结构之哈希——学习笔记

今天看网课学习了哈希的数据结构&#xff0c;写下这一篇博客记录自己的学习过程。 1.哈希简介&#xff1a; 我们发现某些时候映射到小集合的时候会同时有多个值映射到一个下标里面&#xff0c;所以接下来是这种情况的解决方案1&#xff1a; 我们考虑当两个数字映射之后的结果…

提升网络安全重要要素IP地址

在数字化时代&#xff0c;网络安全已经成为人们关注的焦点。本文将深入探讨网络安全与IP地址之间的紧密联系&#xff0c;以及IP地址在构建数字世界的前沿堡垒中的关键作用。 网络安全是当今数字社会中不可忽视的挑战之一。而IP地址&#xff0c;作为互联网通信的基础协议&#…

视频融合云平台/智慧监控平台EassyCVR告警警告出错是什么原因?该如何解决?

视频集中存储/云存储/视频监控管理平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;实现视频资源的鉴权管理、按需调阅、全网分发、智能分析等。AI智能/大数据视频分析EasyCVR平台已经广泛应用在工地、工厂、园区、楼…

Graceful Response 构建 Spring Boot 下优雅的响应处理

一、Graceful Response Graceful Response 是一个 Spring Boot 技术栈下的优雅响应处理器&#xff0c;提供一站式统一返回值封装、全局异常处理、自定义异常错误码等功能&#xff0c;使用Graceful Response进行web接口开发不仅可以节省大量的时间&#xff0c;还可以提高代码质…