IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 排序算法原理及实现 -> 正文阅读

[数据结构与算法]排序算法原理及实现

稳定性:

例:原序列中假设(3,1)和(3,7)的顺序是(3,1)(3,7),如果排完序,这两个顺序没变,还是(3,1)(3,7),就说明是稳定的,如果变了,就说明不稳定。

冒泡排序方法:从第一个数开始,每次只对比两个数,如果后面的比前面的小则交换位置,否则不换位置,拿较大的数继续往后比对,一直跑到最后。

两种循环实现冒泡排序:

?

选择排序方法:第一步从序列中选出最小的和第一个换位置;第二步从剩余的数中选出最小的和第二个换位置;依次进行。(不稳定:升序,选择最大的数的时候会不稳定。)

选择排序实现:

?

插入排序方法:把序列分成两部分,第一个数视为第一部分有序数列,剩余的是无序的。从无序中拿出一个和有序数列,从后往前对比,碰到比它大的继续往前比较,直到碰到比它小的停止。

插入排序实现:

希尔排序方法:取一定的步长,根据步长先分出数个序列,对每一个进行插入排序。后减小步长重新分出序列,继续进行插入排序,直到步长为1,或者排序完成。

希尔排序实现:

?代码前问题解决:

1.如何判断排序完成:---没判断,就持续缩短步长去执行,但由于使用的是while 循环,中间有break 跳出,所以如果顺序原本就是正常的,时间复杂度会降低。

2.减去步长后,超出索引范围怎么办?---循环增加条件 i > 0 的时候执行即可。

3.步长怎么选?---可以使用减半的方式,但不能保证是最优的。

4.要搞出子序列再挨个排序好麻烦---没搞出子序列,而是使用一次循环,通过减去步长的方式对“等价子序列”进行了排序。

快速排序方法(重要):设置两个指针,左边定为low(即比抽出的数小),右边定为high(比抽出的数大)。抽出第一个数a,开始移动指针,若low所指的数比a小,则继续移动,反之开始移动high指针,若high所指的数比a大,则继续移动,反之停止,交换两个指针所指的数,重复以上移动指针+交换数据的步骤,直到找到a的正确位置。之后左右两边均执行相同操作。

快速排序实现:

代码过程中问题解决:

1.递归使用时,传入的列表应当是列表本身,并对本身的某段进行处理,才会对列表本身修改。如果递归以切片的形式传入到函数中,其实是对产生的新列表处理,无法达到排序效果。

2.左右两个指针不能使用同一个循环跑,否则第一遍循环可能是对的,但是第二遍的时候就又会对不该处理的指针进行处理。因此,让两个指针有各自的循环最合适。

3.递归终止条件是什么?最终分的每部分只剩1个数据的时候就完成了递归,此时两个指针位置一样,所以索引相等。但不能设置成start == end,而是需要start>=end就终止。否则可能在最后一步,当start就是最后一个数据的时候,传入的数据是start+1,就会出现超出索引(当设置好比end大的时候就会返回,不会出现这个错误。),也可能出现无限递归。

4.时间复杂度最优是O(nlogn),最坏是O(n^2)。

最优:每次分成两半的时候,都正好全是偶数,每一个都正好能分成两半,最终分的每一个都只剩一个,因此会分2*2*2*2...次,每分一次就乘2,所以最终分的次数就是求分了2的多少次才把n分成了单个的(拆分之前用了循环)。也就是log2为底的n,时间复杂度为logn,那么每一次分完都需要进行一次快速排序,相当于遍历一次,时间复杂度是O(n),那么整体的就是O(nlogn)。

最坏:每次分的时候,就分出了一个数据,所以纵向需要分n次。整体就是n*n

归并排序方法:将列表对半拆分,再对小列表对半拆分,再对半一直到所有小列表都只剩1个元素。之后,将每一对小列表按照数据大小顺序合并成中列表,再同样的方法把中列表一步一步合成大列表,最终完成排序。使用递归方法。

归并排序实现:

?

代码过程中问题解决:

1.使用递归时,主要看三个部分:前两层的拆分方式最后两层的合并方式及返回值;以及拆到头之后的返回值

2.拆分完列表到哪去了,怎么找到他们使用?--拆分完找不到他们,因为还在通过“前两层的拆分方式”继续拆,只有拆到最后一个了,使用“拆到头之后的返回值”,才可以找到最后一个小列表,然后通过“最后两层的合并方式及返回值”,把小列表合并才能得到上一级列表的返回值。因此使用的时候是通过递归逐步合并,就假装合并完了,想想返回值是什么,直接用返回值进行后面的操作实现就行。

3.归并排序是创建了新的列表,因此原列表并未改变,最终需要将返回值赋给一个新变量才可打印出来。并且由于有新的列表,是需要占额外的存储空间的。

4.拆分的时候,时间复杂度是O(1),因为是直接使用了切片的方式,也没有循环。合并时,横向是n,纵向是logn,类似于快速排序。因此时间复杂度是nlogn。稳定。最好最坏的时间复杂度一致。

搜索:在一个特定的项目集合中找到一个特定的项目。

二分法查找:也叫做折半查找,从序列的中间位置截一下,跟中间数据对比,看看所需要找的数据落在哪一半,就在那一半继续从中间位置截,重复此操作。二分法特点:操作对象必须有序并且有下标,因此只能用顺序表。

二分法递归实现:

二分法非递归实现:非递归操作的是下标,不对列表进行修改。

代码中问题解答:

1.递归的结束条件,应当设置一个条件,在符合这个条件的情况下进行递归,如果不符合就直接返回。

2.和中间位置对比后,无论是前一段还是后一段数据,都不包含中间数据。不要忘记+1等操作进行调整。

3.时间复杂度:最优为O(1),比如第一个中间值就是需要找的。最坏为logn,假设n=4, 第一次减半后,两边为2,第二次减半为1,抵达终点。要求2的多少次方等于n:假如n=4,则结果为2,时间复杂度就是log2为底4的对数 = 2。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-30 12:27:46  更:2021-08-30 12:29:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 23:43:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码