排序算法的稳定性
排序算法相信大部分同学都非常熟悉,也是必备知识点。但我也相信,有相当一部分同学被问到哪些排序算法的稳定的??这个问题时,还是一脸懵逼。然后开始百度,取找类似这样的表(此处举例,如有侵权,立即删除):
那么,令人闻风丧胆的排序算法的稳定性到底是什么?理解性记忆究竟难不难?
先来看看排序算法稳定性的定义:
假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。
简单的说就是,两个相等的数,排序后他们相对顺序可能发生改变就说这个算法不稳定。(比如数组中有两个3,原来在前面的3还要保证在前面,否则就是不稳定)
清楚了定义,就可以去看看哪些算法是稳定的,哪些不稳定了。
- 按顺序一个个比较的一般都是稳定的,因为只要相等,不交换就行了,比如冒泡、插入;
- 不破坏顺序分组分治的一般也是稳定的,如归并;
- 破坏原有顺序的都是不稳定的,如不断交换数据的快排、按照不同步长对元素进行插入排序的希尔排序、存在跨多位进行数的交换的选择排序;
- 堆的结构是节点 i i i 的孩子为 2 i 2i 2i 和 2 i + 1 2i+1 2i+1 节点,父节点和子节点会进行比较交换,所以也是非连续的,堆排序显然不稳定;
冒泡算法
基本思想:不断遍历数列,一次比较两个元素,若顺序错误就进行交换。重复多次,最小或最大的元素就会不断被交换到顶端,因此得名。
def bubble_sort(a, n):
for i in range(n - 1, 0, -1): # 更新遍历终点,注:Python是前闭后开
flag = 0
for j in range(0, i): # 遍历范围从第一个数到遍历终点
if a[j] > a[j + 1]: # 遍历过程中不断将大的数交换到右侧,最大的数最终被推到最右侧,不再参与排序,所以每一次遍历范围可以缩小一个单位
a[j], a[j + 1] = a[j + 1], a[j]
flag = 1
if not flag: # 如果没发生交换行为,则直接退出
break