刷题系列——排序算法

参考:README - 十大经典排序算法

1)排序算法分为内部外部排序两种,这个之前并不了解,外部排序需要访问外存的这个就是指需要额外内存比如另一个list或者dict存储中间结果。

2)稳定性:排序后 2 个相等键值的顺序和排序之前它们的顺序相同,这点之前也不了解。

1. 冒泡排序:每次比较两个元素,随着遍历数组,最小的元素会浮到数组顶端。

        1. 做完第一次遍历,最大的元素会到数组末端;每一次保证一个元素到了正确的位置,因此之后的遍历会逐渐缩短长度。

        2. 实现: j和i的边界可以注意一下,当前是优化的写法。

def bubble_sort(lista):num = len(lista)for j in range(1, num):for i in range(num - j):if lista[i] > lista[i + 1]:lista[i], lista[i + 1] = lista[i + 1], lista[i]print(lista)return listalista = [1,5,6,3,7,9,1]
bubble_sort(lista)

        3. 复杂度:最小O(n)是已经正序,最大O(n^2)是倒序,平均O(n^2),空间复杂度O(1),稳定,In-place。

2. 选择排序:每次遍历选择出最大/小元素放在尾/首,下一次选择次之。

        1. 需要记录最大/小元素的索引,涉及到交换最大/小元素和首/尾元素。

        2. 实现        

def select_sort(lista):num = len(lista)for i in range(num - 1):min_ele = ifor j in range(i + 1, num):if lista[j] < lista[min_ele]:min_ele = jlista[i], lista[min_ele] = lista[min_ele], lista[i]print(lista)return lista

        3. 复杂度:最小O(n^2),最大O(n^2),平均O(n^2),空间复杂度O(1),不稳定,In-place。

        4. 不稳定这个点需要注意,涉及到交换位置,所以相同大小元素本来的顺序会被打乱。

3. 插入排序:类比扑克牌

        1. 保证一个已排列数组,插入的数据从后扫描已排列数组然后插入。

        2. 把一个数组划分已排列和未排列待插入部分。

        3. 实现:注意j的变化, j -= 1

def insert_sort(lista):num = len(lista)for i in range(1, num):j = iwhile j - 1 >= 0 and lista[j] < lista[j - 1]:lista[j - 1], lista[j] = lista[j], lista[j - 1]j -= 1print(lista)

        4. 最小O(n),最大O(n^2),平均O(n^2),空间复杂度O(1),稳定,In-place。

4. 希尔排序:递减增量排序算法

        1. 对插入排序的优化:将待排序部分划分为子序列,各自基本有序后,之后再插入排序。包含有归并的思路。

        2. 子序列的划分方式是很重要的,如果连续几个数划分为一个子序列,对整体效率是无影响的,因此需要采用增量划分。

        3. 增量是指划分的子序列的个数,增量递减直到为1,排序结束。

​​​​​​​

        3. 不稳定因为子序列的排序会打乱原顺序。

        4. 实现

def shell_sort(lista):num = len(lista)increment = num // 2while increment > 0:for i in range(increment, num):idx = iwhile idx >= increment and  lista[idx] < lista[idx - increment]:lista[idx], lista[idx - increment] = lista[idx - increment], lista[idx]idx -= incrementincrement //= 2print(lista)

        5. 最小O(nlgn),其他不太确定,空间复杂度O(1),不稳定因为包含了插入排序,In-place。

5. 归并排序:分治法,需要额外空间

        1. 分为自上而下的递归和自下而上的迭代,这点还不是很理解。

        2. 参考:【Python入门算法23】排序入门:高效的归并排序 mergesort 的4种写法 - 知乎

        3. 实现

    
def merge_sort(lista):if len(lista) == 1:return listaidx = len(lista) // 2left = merge_sort(lista[:idx])right = merge_sort(lista[idx:])merged = merge_1(left, right)print(merged)return mergeddef merge(lista, listb):merged = []a, b = len(lista), len(listb)i, j = 0, 0while i < a and j < b:if lista[i] < listb[j]:merged.append(lista[i])i += 1else:merged.append(listb[j])j += 1merged.extend(lista[i:])merged.extend(listb[j:])return mergeddef merge_1(lista, listb):if not lista:return listbif not listb:return listaif lista[0] < listb[0]:return [lista[0]] + merge_1(lista[1:], listb)else:return [listb[0]] + merge_1(lista, listb[1:])

6. 快速排序:采用分治法

        1. 找到基准,基准左边比基准小,右边比基准大。

        2. 对冒泡排序的改进,是内部排序的最优。

        3. 实现 

def quick_sort(lista, start, end):if start >= end:return lista[start:end]pivot = lista[start]left = startright = endwhile left < right:while lista[right] >= pivot and left < right:right -= 1while lista[left] < pivot and left < right:left += 1lista[left], lista[right] = lista[right], lista[left]lista[left] = pivotquick_sort(lista, start, left-1)quick_sort(lista, left+1, end)print(lista)

7. 堆排序:利用堆的数据结构,大顶堆用于升序排序和小顶堆用于降序排序

        1. 构建堆,交换堆元素,重新构建堆

        2. 参考:​​​​​​​Python实现堆排序_堆排序python-CSDN博客

        3. 实现 

def heap_sort(lista):idx = len(lista) // 2 - 1for i in range(idx, -1, -1):heapify(lista, i, len(lista) - 1)for i in range(len(lista) - 1, -1, -1):lista[i], lista[0] = lista[0], lista[i]heapify(lista, 0, i - 1)print(lista)return listadef heapify(lista, start, end):root = startleft = root * 2 + 1while left <= end:if left + 1 <= end and lista[left] < lista[left + 1]:left += 1if lista[root] < lista[left]:lista[root], lista[left] = lista[left], lista[root]root = leftleft = root * 2 + 1else:break 

        4. 平均复杂度Ο(nlogn),不稳定。

8. 计数排序:需要额外空间

        1. 将输入的值转化为key存储在额外的空间中

        2. 实现

def counting_sort(lista):n = len(lista)min_v = 222222222max_v = 0for ele in lista:if ele > max_v:max_v = eleif ele < min_v:min_v = elenum = max_v - min_v + 1listb = [0] * numfor i in lista:listb[i - min_v] += 1idx = 0for i in range(max_v - min_v + 1):for j in range(listb[i]):lista[idx] = i + min_vidx += 1print(lista)return lista

        3. 平均复杂度Ο(n+k),这个k的部分暂时不是很理解,空间复杂度O(k)。Out-place,不稳定。

9. 桶排序:计数排序的升级版

        1. 包括分桶和合并两部分,对桶内的数据进行排序,再把桶内排序好的数据取出,又称为箱排序

        2. 实现:里面调用了冒泡排序,调用快排时发现上面的代码有问题

def bucket_sort(lista):listb = []min_value = 222222222222max_value = 0for i in lista:if i > max_value:max_value = iif i < min_value:min_value = ibucket_num = (max_value - min_value) // 3 + 1buckets = [[] for i in range(bucket_num)]for i in lista:buckets[(i - min_value) // 3].append(i)print(buckets)for b in buckets:b = bubble_sort(b)print(b)listb.extend(b)print(listb)

        3. 是否稳定决定于桶内的排序算法。最快情况是数据被桶平分(n/k),具体复杂度决定于桶内的排序算法。

10. 基数排序:非比较型的排序算法,和桶排序思想类似

        1. 除了对整数排序,也可以用于浮点数,字符串等。

        2. 按位数分桶,分为MSD,LSD两种方法。

        3. 实现

def radix_sort(lista):max_value = max(lista)place = 0while max_value >= 10 ** (place):place += 1buckets = [[] for i in range(10)]for i in range(place):for j in lista:ele = j % (10 ** (i + 1))buckets[ele].append(j)k = 0for bucket in buckets:if bucket:lista[k] = bucket.pop(0)k += 1print(lista)

        4. 时间复杂度O(d(n+k)),d是最大值的位数,k是桶个数,n是队列长度。稳定,Out-place。

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

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

相关文章

openGauss训练营培训课程第1课时

课时1:openGauss全景介绍 1、介绍 openGauss 全景 1.1.openGauss总体架构介绍 本章节主要介绍了openGauss发展的历史&#xff0c;现状以及未来。对当前的DataPod和DataKit 2种openGauss当前主推的场景化产品进行了介绍。同时对openGauss的整个逻辑模块的视图进行了讲解。 …

算法通关村第十三关-黄金挑战数论问题

计数质数 描述 : 给定整数 n &#xff0c;返回 所有小于非负整数 n 的质数的数量 。 题目 : LeetCode 204.计数质数 : 204. 计数质数 分析 : 解决这个题有一个有效的方法&#xff0c;叫埃氏筛 , 后来又产生了线性筛&#xff0c;奇数筛等改进的方法。 基本思想是如果 x是…

12.04 二叉树中等题

513. 找树左下角的值 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1 思路&#xff1a;找到最低层中最左侧的节点值&#xff0c;比较适合层序遍历&#xff0c;返回最…

【动态规划】LeetCode-198/LCR089.打家劫舍

&#x1f388;算法那些事专栏说明&#xff1a;这是一个记录刷题日常的专栏&#xff0c;每个文章标题前都会写明这道题使用的算法。专栏每日计划至少更新1道题目&#xff0c;在这立下Flag&#x1f6a9; &#x1f3e0;个人主页&#xff1a;Jammingpro &#x1f4d5;专栏链接&…

MS85163实时时钟/日历可Pin to Pin兼容PCF8563

MS85163/MS85163M是一款CMOS实时时钟(RTC) 和日历电路&#xff0c;针对低功耗进行了优化&#xff0c;内置了可编程的时钟输出、中断输出和低电压检测器。可Pin to Pin兼容PCF8563。所有寄存器地址和数据都通过两线双向I 2C总线进行串行传输&#xff0c;最大总线传输速度为 400k…

2023年【上海市安全员C3证】新版试题及上海市安全员C3证试题及解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 上海市安全员C3证新版试题是安全生产模拟考试一点通总题库中生成的一套上海市安全员C3证试题及解析&#xff0c;安全生产模拟考试一点通上上海市安全员C3证作业手机同步练习。2023年【上海市安全员C3证】新版试题及上…

干货分享:盘点8款优秀的自动化测试工具

如今&#xff0c;作为一名软件测试工程师&#xff0c;几乎所有人都需要具备自动化测试相关的知识&#xff0c;并且懂得如何去利用工具&#xff0c;来为企业减少时间成本和错误成本。这是为什么呢&#xff1f; 在以前&#xff0c;测试人员一般都只需要扮演终端用户&#xff0c;…

用Python创建日历详细指南与实用示例

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是彭涛&#xff0c;今天为大家分享 用Python创建日历详细指南与实用示例&#xff0c;全文4800字&#xff0c;阅读大约15分钟。 在日常生活和工作中&#xff0c;创建和管理日历是一项关键任务。Python提供了丰富…

【ArcGIS Pro微课1000例】0047:深度学习--棕榈树提取全流程

一、创建训练样本 对汤加科洛瓦伊种植园每棵棕榈树的健康状况进行清查和评估,这需要花费大量的时间和劳动力。 为简化此过程,将在 ArcGIS Pro 中使用深度学习模型来识别树木,然后根据植被绿度的测量值计算其健康状况。 第一步是找到显示汤加科洛瓦伊的影像,该影像具有足够…

无需服务器,无需魔法,拥有一个微信机器人就是这么简单

前情提要 还没看过的朋友可以看一下上一篇文章《拥有一个微信机器人总共需要几步&#xff1f;》在这篇文章里&#xff0c;我们提到&#xff0c;创建微信机器人需要一个大前提--你得有一台服务器。现在&#xff0c;不再需要了&#xff01;没错&#xff0c;上一篇提到的Serverles…

巧借C++算法实现冒泡排序算法

目录 引言冒泡排序原理具体实现步骤示例代码时间复杂度和稳定性优化可能性结束语 引言 作为计算机专业出身的开发者&#xff0c;以及从事软件开发相关的小伙伴&#xff0c;想必对C语言并不陌生&#xff0c;它是一门非常厉害的编程语言&#xff0c;不仅是基于程序底层的语言&a…

JavaSE基础50题:9. 求1~100内的所有素数

【概述】 素数&#xff1a;只能被1和自己整除。 素数的判断方法&#xff1a; 我们把非素数都写成 ab 的形式&#xff0c;如&#xff1a; 16 116 16 28 24 124 24 212 24 38 24 46 同样&#xff0c;我们发现&#xff0c;a 和 b 其中一定会有一个数字 < 根号n&#xff0…

SIT2596,可替代LM2596,40V 输入 150KHz 3A 降压型电源转换器

SIT2596 是一款降压型开关电压调节芯片&#xff0c;可固定输出 3.3V、5V、12V&#xff0c;也可根据需要调节 输出电压&#xff0c;电压输出范围在 1.2V-37V&#xff0c;输入电压最高可达 40V,输出电流可达 3A;同时具有优异 的线性调整率和负载调整率。 SIT2596 内部集成频率…

中危漏洞!小程序优惠卷遍历

进入小程序&#xff0c;因为是一个小商城&#xff0c;所以照例先查看收货地址是否存在越权&#xff0c;以及能否未授权访问&#xff0c;但是发现不存在这些问题&#xff0c;所以去查看优惠卷 进入领券中心&#xff0c;点击领取优惠券时抓包 发现数据包&#xff0c;存在敏感参数…

DevEco Studio将常用内容设为代码模板 通过快捷键调出

有时候 我们开发 可能有一些经常要写的内容 天天CV大法找东西也非常麻烦 我们这里打开编辑器 选择 File下的Settings 打开设置界面 选择 Editor 下的 Live Templates 模板 然后 我们点击右侧加号 然后点第一个 加一个 这里 我们设置 输入 em时会触发提示 内容时 问君能有几…

使用Serv-U FTP服务器共享文件,实现无公网IP环境下远程访问

文章目录 1. 前言2. 本地FTP搭建2.1 Serv-U下载和安装2.2 Serv-U共享网页测试2.3 Cpolar下载和安装 3. 本地FTP发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1. 前言 科技日益发展的今天&#xff0c;移动电子设备似乎成了我们生活的主角&#xff0c;智能…

网盘系统设计:万亿 GB 网盘如何实现秒传与限速?

Java全能学习面试指南&#xff1a;https://javaxiaobear.cn 网盘&#xff0c;又称云盘&#xff0c;是提供文件托管和文件上传、下载服务的网站&#xff08;File hostingservice&#xff09;。人们通过网盘保管自己拍摄的照片、视频&#xff0c;通过网盘和他人共享文件&#xff…

C++进阶篇6---lambda表达式

目录 一、lambda表达式 1.引入 2、lambda表达式语法 二、包装器---function 1.引入 2.包装器介绍 三、bind 一、lambda表达式 1.引入 class Person { public:Person(int age,string name):_age(age),_name(name){} //private://方便后面的举例int _age;string _name…

JS生成登录验证码

采用js生成登录的验证码 采用的技术点有html&#xff0c;css&#xff0c;JS&#xff0c;jQuery HTML&#xff1a; <div class"box_b"><img src"./img/0775639c-c82c-4a29-937f-d2a3bae5151a.png" alt""><div class"regist…

智能变压器监控系统

智能变压器监控系统是一种先进的物联网技术和智能设备&#xff0c;能够实现对变压器的实时监测和管理&#xff0c;提高变压器的运行效率和可靠性&#xff0c;为用户提供及时、准确的变压器运行状态信息和故障预警。 力安科技A30变压器云控终端是一款集变压器温控仪、变压器运行…