| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> 洛谷题单 Part2.2 排序算法(十种常见的排序算法) -> 正文阅读 |
|
[数据结构与算法]洛谷题单 Part2.2 排序算法(十种常见的排序算法) |
瞄了一眼题 发现都是直接 s o r t sort sort就可以过的题 所以我决定从头学一下排序算法 不要浪费这个复习排序算法的机会 0. 0. 0.排序的介绍排序算法 顾名思义就是把无序变为有序 对象可以是数组 或者链表等 常见的排序算法大概有10种左右 如下图 1. 1. 1.各种排序的原理及实现冒泡排序冒泡排序的本质是交换 对于每个数 与他相邻的数作比较 如果左边的数大(小) 那就进行交换 否则不交换 那么这样操作一轮下来 最右侧的数一定是最大(小)的 多次进行操作后得到的是一个升(降)序的一个排列 因为这样一个一个往上窜的形式很像冒泡泡 所以被称为冒泡排序 时间复杂度O ( n 2 ) O(n^2) O(n2) 最好情况是一个数组本身就是有序的 这时的时间复杂度是 O ( n ) O(n) O(n) 上代码(我写的是升序排列)↓ 选择排序选择排序我感觉是一种比较像人类肉眼排序用的方法 非常简单粗暴 从数列里找到最小(大)的数 将其放在第一位 再从剩余数列中找到最小(大)的数 将其放在第二位 以此类推 最后会排除一个升(降)序的数组 时间复杂度O ( n 2 ) O(n^2) O(n2) 上代码↓ 插入排序插入排序可以形象地理解为码牌的过程 每抓到一张牌 要把它插入手里的牌堆中 时间复杂度
O
(
n
2
)
O(n^2)
O(n2) 最优情况是数组有序 线性复杂度
O
(
n
)
O(n)
O(n) 希尔排序在希尔排序出现之前,大家普遍认为排序算法的复杂度不会优于
O
(
n
2
)
O(n^2)
O(n2) 直到
D
.
L
.
S
h
e
l
l
D.L.Shell
D.L.Shell在
1959
1959
1959年发布了以自己命名的这个算法
针对第二种性质 希尔做出了以下优化 每次对间隔为
g
a
p
gap
gap的元素进行普通插入排序 然后缩小
g
a
p
,
gap,
gap,对新的
g
a
p
gap
gap进行一样的操作 即对间隔为
g
a
p
gap
gap的元素进行普通插入排序。最后
g
a
p
gap
gap为
1
1
1的时候就是插入排序 但是由于这个数组已经部分有序了 所以进行插入排序的步骤会比直接插入排序的步骤少很多。其中称
g
a
p
gap
gap为增量,
g
a
p
gap
gap组成的序列为增量序列。因其是逐次递减的,故希尔排序也被称为增量递减排序。希尔使用的增量序列是
1
,
2
,
4
,
8
,
.
.
.
,
{1, 2, 4, 8,...},
1,2,4,8,...,即
2
k
,
k
=
1
,
2
,
3
,
.
.
.
,
2^k,k = 1, 2, 3, ...,
2k,k=1,2,3,...,,一般称其为希尔增量。 时间复杂度希尔排序的时间复杂度和选取的增量序列有关 原理先说一个大家都会的概念 逆序数(打开我的线代教材 上代码 我们以
S
e
d
g
e
w
i
c
k
Sedgewick
Sedgewick增量做为增量序列 (最坏复杂度为
O
(
n
4
/
3
)
O(n^{4/3})
O(n4/3)) 归并排序归并排序哈哈哈 这个有故事的算法 之前初中的时候教练说我们抄代码就让我们打归并排序验证到底是不是抄的 可是考试的题和排序一点关系没有捏 老师就总说我抄代码 后来自己学了归并排序 他就开始找别的地方的毛病了哈哈 首先 对于两个已经排好序的数组 将他们合并成一个有序的大数组所需时间为
O
(
n
+
m
)
O(n+m)
O(n+m) 归并排序的思路就是将数组先分为 2 2 2部分,然后将这两部分分别操作为有序数组,再将这两个数组利用上述操作线性完成排序。我们称这个操作为分割 那么如何将这两部分分别变成有序数组呢,那就是一个递归问题了,将这两个数组再分别利用分割操作分成两部分,直到某一部分长度为 2 , 2, 2,此时再将其分为两部分,因为数组长度为 1 1 1一定是有序数组,所以这时可以将这两部分利用合并操作在一起,以此类推,最后得到的就是有序数组 时间复杂度对于每个合并操作都为线性复杂度,对于分割操作需要进行 O ( l o g n ) O(log_n) O(logn?)次,因此时间复杂度为 O ( n l o g n ) O(nlog_n) O(nlogn?) 上代码 归并排序的应用求逆序数 上题 P1908 逆序对传送门
快速排序与归并排序一样,快速排序也是利用分治和递归的思想 时间复杂度与主元的选取有关
(
1
)
(1)
(1) 主元为起始元素 每次选取当前数组第一个元素作为主轴。 优点:避免了主元为起始元素时对于基本有序的输入,因不能均匀分割数组导致复杂度退化的情况。 优点:实现相对简单,且有效避免简单快排中的劣质分割。 P1177 【模板】快速排序传送门
堆排序堆排序 顾名思义就是要用到堆这个数据结构的排序 那就浅浅说两句堆 计数排序听到这个名字你可能会感觉云里雾里,好高大上的名字配上nb的线性复杂度 你一定会以为他是什么高级算法 由于后面两个算法基本不会用到 所以这里代码粘的外面的 如果有错误请xdm指正 桶排序基于上述排序,我们考虑如果数非常大,想用类似计数排序应该怎么做,这就有了桶排序 时间复杂度最优:当输入的数据可以均匀的分配到每一个桶中 此时时间复杂度为
O
(
n
+
k
)
O(n+k)
O(n+k) 基数排序基数排序也是对计数排序的一个升级改良版本 操作过程如下 上题上题 一般在计算机竞赛里我们通常排序直接用 s o r t sort sort函数 所以题一般都比较水 P1177 【模板】快速排序传送门 P1059 [NOIP2006 普及组] 明明的随机数传送门
P1068 [NOIP2009 普及组] 分数线划定第一眼除了结构体没想到什么好的方法能存
i
d
id
id号
P1051 [NOIP2005 提高组] 谁拿了最多奖学金传送门
P1309 [NOIP2011 普及组] 瑞士轮传送门
P1908 逆序对传送门 总结排序算法一直是
O
I
OI
OI界的入门算法,其灵活多变的形式也激发了我们对程序设计竞赛的热爱。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
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年12日历 | -2024/12/28 18:27:27- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |
数据统计 |