《计算之魂》Task3:关于排序的讨论
《计算之魂》Task3
- 1. 排序
- 1.1 评价指标
- 1.2 不同排序算法*O*(n)分类
- 2. 算法介绍
- 2.1 选择排序
- 2.2 插入排序
- 2.3 归并排序
- 2.4 堆排序
- 2.5 快速排序
- 3. 思考题
- 思考题1.4.1 赛跑问题(GS)
- 思考题1.4.2 区间排序
1. 排序
所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减排列起来的操作。排序是计算机内经常进行的一种操作,其目的是将一组无序的记录序列调整为有序的记录序列。
1.1 评价指标
- 时间复杂度
- 空间复杂度
- 使用场景:针对实际对节省时间和空间的不同需求,选择适用于不同场景的排序算法
- 稳定性:稳定的算法在排序过程中不会改变元素彼此之间次序
1.2 不同排序算法O(n)分类
排序算法 | 平均时间复杂度度 | 最坏时间复杂度 | 额外空间复杂度 | 稳定性 |
---|---|---|---|---|
选择排序 | O(n2)O(n^2)O(n2) | O(n2)O(n^2)O(n2) | O(1)O(1)O(1) | 稳定 |
插入排序 | O(n2)O(n^2)O(n2) | O(n2)O(n^2)O(n2) | O(1)O(1)O(1) | 稳定 |
归并排序 | O(n∗logn)O(n*\log n)O(n∗logn) | O(n∗logn)O(n*\log n)O(n∗logn) | O(n)O(n)O(n) | 稳定 |
堆排序 | O(n∗logn)O(n*\log n)O(n∗logn) | O(n∗logn)O(n*\log n)O(n∗logn) | O(1)O(1)O(1) | 不稳定 |
快速排序 | O(n∗logn)O(n*\log n)O(n∗logn) | O(n2)O(n^2)O(n2) | O(logn)O(\log n)O(logn) | 不稳定 |
2. 算法介绍
2.1 选择排序
python 实现
def selection_sort(num_list):length = len(num_list)if length <= 1:return num_listfor j in range(length):# 假设第一个元素为最小元素min_num_index = j# 遍历未排序区域元素,以此和未排序区域的第一个元素做对比for i in range(j+1, length):if num_list[i] < num_list[min_num_index]:min_num_index = i# 交换位置num_list[min_num_index], num_list[j] = num_list[j], num_list[min_num_index]return num_list
2.2 插入排序
python 实现
def insertion_sort(ls):for i in range(0,len(ls)):current_index = iwhile ls[current_index - 1] > ls[current_index] and current_index - 1 >= 0:ls[current_index] , ls[current_index - 1] = ls[current_index - 1] , ls[current_index]current_index -= 1return ls
2.3 归并排序
python 实现
# 1.将整个数组对半分开,直到只剩一个元素# 2.从一个元素开始往回进行对比合并,将合并的内容暂且放在一个空列表中# 定义合并merge函数
def merge(L,R):# 将两个排过序的两个列表进行合并并排序# 分别用于限定L、R的数据减少情况i, j = 0,0# 用于存放L与R的合并内容res = []while i < len(L) and j < len(R):# 如果左边的数大于右边的数,就将左边的数先添加到res中,再继续比较(合并的R、L已经排过序)# 如果如果右边的数大于左边的数,就将右边的数先添加到res中,再继续比较(合并的R、L已经排过序)if L[i] <= R[j]:res.append(L[i])i += 1else:res.append(R[j])j += 1# 因为当 i == len(L) 或者 j == len(R)时,跳出while循环,且每次循环只处理一个列表里的内容,所以其中有一个列表内容会先全部加入res中,另一个列表还剩内容未加进res中。# 对未处理完的列表,直接加入res中res += R[j:] if i == len(L) else L[i:]return res# 定义排序merge_sort函数
def merge_sort(List):length = len(List)if length <= 1:return Listelse:mid = length//2left = merge_sort(List[:mid])right = merge_sort(List[mid:])return merge(left,right)
参考资料:归并排序(Python代码)
2.4 堆排序
演示动画
原理及代码可参考python实现堆排序
2.5 快速排序
演示动画
python 代码
def quicksort(array):if len(array) < 2:return arrayelse:pivot = array[0]less = [i for i in array[1:] if i <= pivot]greater = [i for i in array[1:] if i >= pivot]return quicksort(less) + [pivot] + quicksort(greater)
3. 思考题
思考题1.4.1 赛跑问题(GS)
假定有25名短跑选手比赛争夺前三名,赛场上有五条赛道,一次可以有五名选手同时比赛。比赛并不计时,只看相应的名次。假设选手的发挥是稳定的,也就是说如果约翰比张三跑得快,张三比凯利跑得快,约翰一定比凯利跑得快。最少需要几次比赛才能决出前三名?(在第6章给出了这一问题的解答。(难度系数3颗星))
答:参考了计算之魂第6章给出了的解答。
- 先进行五组比赛,决出各组名次。并令各组第一分别为A1、B1、C1、D1、E1。
A组 | B组 | C组 | D组 | E组 |
---|---|---|---|---|
A1 | B1 | C1 | D1 | E1 |
A2 | B2 | C2 | D2 | E2 |
A3 | B3 | C3 | D3 | E3 |
A4 | B4 | C4 | D4 | E4 |
A5 | B5 | C5 | D5 | E5 |
- 第六组比赛:各组第一 A1、B1、C1、D1、E1 分别进行一次比赛。假设名次为 A1、B1、C1、D1、E1 。则整体第一名为A1。
- 第七组比赛:如下表,整体第二名必出现在 A2、B1之间;整体第三名必出现在 A2、B1、 A3、B2、C1 之间。
A2、B1、 A3、B2、C1 之间进行第七组比赛,第一名为整体第二名,第二名为整体第三名。
A组 | B组 | C组 | D组 | E组 |
---|---|---|---|---|
B1 | C1 | D1 | E1 | |
A2 | B2 | C2 | D2 | E2 |
A3 | B3 | C3 | D3 | E3 |
A4 | B4 | C4 | D4 | E4 |
A5 | B5 | C5 | D5 | E5 |
思考题1.4.2 区间排序
如果有N个区间[l1,r1],[l2,r2],…,[lN,rN],只要满足下面的条件我们就说这些区间是有序的:存在xi∈[li,ri],其中i=1,2,…,N。
比如,[1, 4]、[2, 3]和[1.5, 2.5]是有序的,因为我们可以从这三个区间中选择1.1、2.1和2.2三个数。同时[2, 3]、[1, 4]和[1.5, 2.5]也是有序的,因为我们可以选择2.1、2.2和2.4。但是[1, 2]、[2.7, 3.5]和[1.5, 2.5]不是有序的。
对于任意一组区间,如何将它们进行排序?(难度系数3颗星)
答:该题解答参考了博客《计算之魂》思考题1.4 - Q2,内容如下:
- 按照右端点排序;
- 将右端点最大的区间作为头区间,讨论剩余 n -1 个区间的情况;
- 对剩余的 n - 1 个区间按照步骤二重复,直至仅剩 4 个区间为止(也就是右端点最小的四个区间);
- 如果第 4 个区间不能和第 3 个区间交换,则按照上图可以得到前三个区间的情况,并递归地讨论第 4 个区间与第 5 个区间是否能交换,直至递归到最后一个区间,算法终止;
- 如果能交换,则将第 3 个区间作为最大的区间,并可以得到 N1、N2、N4(按照右端点的相对大小排序)这三个区间的情况,并归位;
- 讨论第 4 个区间能否与第 2 个区间交换,不能的话则返回步骤 4;
- 能的话则返回步骤 5,直至讨论到第 4 个区间与第 1 个区间是否能交换,并返回步骤4。
《计算之魂》Task3:关于排序的讨论相关推荐
- 《计算之魂》读书笔记 04
<计算之魂>读书笔记 04 1.4 关于排序的讨论 [1.4.3]针对特殊情况,我们是否还有更好的答案? [附录]为什么排序算法的复杂度不可能小于 O(nlogn)O(nlogn)O(nl ...
- 《计算之魂》读书笔记
计算之魂(吴军) 引子 计算的本质--从机械到电子 第 1 章 毫厘千里之差--大O概念 1.1 算法的规范化和量化度量 软件为什么从计算机科学中分离出来? 最初计算机是用于计算,而拥有了计算的基础功 ...
- 《计算之魂》第1章 毫厘千里之差——大O概念(1.4节)
1.4 关于排序的讨论 排序算法: 人们曾经研究最多的一类算法 依然是最基础的.在程序中使用频率最高的算法之一 排序算法根据时间复杂度分两类: 复杂度为O(N2)O(N^2)O(N2)的算法 复杂度为 ...
- 【Datawhale202208《吴军计算之魂》】
相关资料: 开源地址:https://github.com/siyuxin/exercises-of-the-soul-of-calculation 开源内容:https://linklearner. ...
- 《计算之魂》阅读笔记 02
<计算之魂>阅读笔记 02 1.3 怎样寻找最好的算法 例题 1.3 方法一:三重循环 方法二:二重循环 方法三:分而治之 方法四:正反扫描 [思考题 1.3.1] [思考题 1.3.2] ...
- 《计算之魂》Task2:怎样寻找最好的算法
<计算之魂>Task2 1. 问题描述 2. 解决方法 2.1 方法1:三重循环 2.2 方法2:两重循环 2.3 方法3:分治算法 2.4 方法4:正.反两遍扫描 2.4.1 通常情况下 ...
- 在学生信息结构体中再添加一个计算平均值和按照平均值排序以及删除指定学号的学生信息
定义一个学生信息结构体,包含姓名,学号,语文成绩.数学成绩,和英语成绩,定义结构体数组存放不同学生的信息,可以在终端录入学生的信息,可以实现对于学生成绩的排序,排序可以按照语文.数学或者英语的任意一个 ...
- 《计算之魂》--- 思考题0.3 【读书笔记】
<计算之魂>- 思考题0.3 题目如下 分别计算一下1946年的 ENIAC 和如今的 华为P30 在一度电的功耗下,能完成多少次计算. ENIAC 根据资料得知 ENIAC每秒计算500 ...
- 计算之魂 寻找最好的算法
寻找最好的算法 1. 实例 以总和最大区间问题为例: 给定一个实数序列,设计一个最有效的算法,找到一个总和最大的区间 暴力解法1:O(n3),暴力枚举左边界和右边界需要O(n2),计算边界内的和需要O ...
- [datawhale202208]计算之魂共读:怎样寻找最好的算法
结论速递 本次通过了解总和最大区间问题(即最大子序和)的四种时间复杂度的求解方法,直观地了解了算法复杂度和最优算法的关系. 同时,了解了对优化算法复杂度的判断包含三个内容:对问题边界的认知,对无用功的 ...
最新文章
- python列表map函数_python中map函数怎么显示结果
- Python读取Excel文件统计演员参演电影
- Java中的重载(overloading)和重写(overriding)
- 使用Nodejs将js文件转换成json文件
- 企业应该了解的ISO27001体系建设指导
- 杰出人士的七种共性之5-独木求林
- 电脑开热点手机连不上
- android 自定义通知铃声设置在哪,安卓手机铃声自定义:短信通知、来电铃声怎么设置?...
- python实现均匀分配_python 实现生成均匀分布的点
- 23.打印由*号组成的三角形图案
- 2022N1叉车司机考题及答案
- 依靠闲鱼赚钱,互联网副业单天500+
- 云中数据_免费备份和共享云中数据的最佳网站
- 在x86和arm编译libmodbus
- js逆向-某岸网络登录参数
- C# Excel导入导出
- 激光光束传输影响matlab仿真,Matlab激光雷达在雨天的测距特性研究
- 南农的计算机专业好就业吗,南京农业大学好就业吗?附南京农业大学就业率最高的专业名单...
- python程序设计基础山东联盟化工集团有限公司_网络选修课答案公众号
- 运行win7计算机需要多长时间,WIN7电脑运行太慢怎么解决
热门文章
- 1分钟了解 rap2
- 最长的指定瑕疵度的元音字串 —— 最优解法(C++实现)
- 【读书笔记】天生不聪明
- 追加安装sticky模块
- Introduction to Reinforcement Learning notes
- 未能加载文件或程序集“XXXX”或它的某一个依赖项。试图加载格式不正确的程序。(已解决)
- 自动化运维---playbook(应用变量)
- 客户服务管理(CSM)
- 【Gitlab】 remote: Ask a project Owner or Maintainer to create a default branch:
- Kubernetes 报错小结