- 简单排序:冒泡(交换)排序、选择排序、插入排序、希尔排序
- 复杂排序:快速排序、堆积排序、基数排序
- 合并排序:合并两个或多个排好序的线性表
稳定排序与不稳定排序:
稳定排序是指一串数字,进过排列以后,同样大小的元素保持原有的顺序。
不稳定排序就是说,排序后,同样大小的元素的顺序可能发生改变。
例如:
排序前有两个数大小为5,分别叫它们
5
1
5_1
51和
5
2
5_2
52,排序前
5
1
5_1
51在
5
2
5_2
52前面,排序后
5
1
5_1
51在
5
2
5_2
52后面,那么这个排序就是不稳定的。
简单排序
冒泡(交换)排序
核心思想:
每次比较相邻两个元素的大小,大的交换到后面去。
一次遍历就可以将最大的元素交换到最后。
时间复杂度:
最好情况为
O
(
n
)
O(n)
O(n),平均为
O
(
n
2
)
O(n^2)
O(n2),最差为
O
(
n
2
)
O(n^2)
O(n2)。
是否是稳定排序:
是。
选择排序
核心思想:
第一次选择最大的元素,和最后一个元素交换位置。
第二次选择前
n
−
1
n-1
n−1个元素中最大的元素和第
n
−
1
n-1
n−1个元素交换位置。
以此类推。
时间复杂度:
最好情况为
O
(
n
2
)
O(n^2)
O(n2),平均为
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),最差为
O
(
n
2
)
O(n^2)
O(n2)。
是否是稳定排序:
是。
希尔排序
核心思想:
将数据分成特定间隔的几个小区快,每次对相应部分的数据进行插入排序,逐渐缩短距离间隔,直至间隔为1。
时间复杂度:
最好情况为
O
(
n
3
/
2
)
O(n^{3/2})
O(n3/2),平均为
O
(
n
3
/
2
)
O(n^{3/2})
O(n3/2),最差为
O
(
n
3
/
2
)
O(n^{3/2})
O(n3/2)。
是否是稳定算法:
否。
复杂排序:
快速排序
核心思想:
选择数据的第一个数K为中间数,从左往右找到第一个比K大的数,从右往左找到第一个比K小的数,若较大的数的位置在较小的数的前面,交换两者的位置,一直到若较大的数的位置在较小的数的后面。交换K和较小的数。
整个数列被K分成了2部分,对相应的部分进行相同操作,直到排序完成。
时间复杂度:
最好情况为
O
(
n
l
o
g
(
n
)
)
O(nlog(n))
O(nlog(n)),平均为
O
(
n
l
o
g
(
n
)
)
O(nlog(n))
O(nlog(n)),最差为
O
(
n
2
)
O(n^2)
O(n2)。
是否是稳定排序:
不是。
堆积排序
核心思想:
将数据用最大堆积树表示,删除树根,将剩余的树用堆积树表示,删除树根,以此类推。
时间复杂度:
最好情况为
O
(
n
l
o
g
(
n
)
)
O(nlog(n))
O(nlog(n)),平均为
O
(
n
l
o
g
(
n
)
)
O(nlog(n))
O(nlog(n)),最差为
O
(
n
l
o
g
(
n
)
)
O(nlog(n))
O(nlog(n))。
是否是稳定排序:
否。
基数排序
核心思想:
将数据按不同的位数进行排序,例如先按个位的大小进行排序,然后再按照十位的大小进行排序,以此类推。
时间复杂度:
最好情况为
O
(
n
l
o
g
p
(
k
)
)
O(nlog_p(k))
O(nlogp(k)),平均为
O
(
n
l
o
g
p
(
k
)
)
O(nlog_p(k))
O(nlogp(k)),最差为
O
(
n
l
o
g
p
(
k
)
)
O(nlog_p(k))
O(nlogp(k))。
是否是稳定排序:
是。
合并排序
核心思想:
针对已经排好顺序的两个或者两个以上的数列,通过合并的方式将其组成一个大的且排好序的数列。
时间复杂度:
最好情况为
O
(
n
l
o
g
(
n
)
)
O(nlog(n))
O(nlog(n)),平均为
O
(
n
l
o
g
(
n
)
)
O(nlog(n))
O(nlog(n)),最差为
O
(
n
l
o
g
(
n
)
)
O(nlog(n))
O(nlog(n))。
是否是稳定排序:
是。
合并排序更详细请点击
参考书籍:《图解数据结构–使用Python》
部分代码请点击