稳定排序算法有哪些
1. 在快速排序、堆排序、归并排序中,什么排序是稳定的
归并排序是稳定的排序算法。
归并排序的稳定性分析:
归并排序是把序列递归地分成短序列,递归出口是短序列只有1个元素或者2个序列,然后把各个有序的段序列合并成一个有序的长序列,不断合并直到原序列全部排好序。
可以发现,在1个或2个元素时,1个元素不会交换,2个元素如果大小相等,没有外部干扰,将不会破坏稳定性。
那么,在短的有序序列合并的过程中,稳定性是没有受到破坏的,合并过程中如果两个当前元素相等时,把处在前面的序列的元素保存在结果序列的前面,这样就保证了稳定性。所以,归并排序也是稳定的排序算法。
(1)稳定排序算法有哪些扩展阅读:
算法稳定性的判断方法:
在常见的排序算法中,堆排序、快速排序、希尔排序、直接选择排序是不稳定的排序算法,而基数排序、冒泡排序、直接插入排序、折半插入排序、归并排序是稳定的排序算法。
对于不稳定的排序算法,只要举出一个实例,即可说明它的不稳定性;而对于稳定的排序算法,必须对算法进行分析从而得到稳定的特性。
需要注意的是,排序算法是否为稳定的是由具体算法决定的,不稳定的算法在某种条件下可以变为稳定的算法,而稳定的算法在某种条件下也可以变为不稳定的算法。
比如,快速排序原本是不稳定的排序方法,但若待排序记录中只有一组具有相同关键码的记录,而选择的轴值恰好是这组相同关键码中的一个,此时的快速排序就是稳定的。
参考资料来源:网络-排序算法稳定性
2. 简单(直接)选择排序的稳定性
简单选择排序是不稳定排序。
假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。
(2)稳定排序算法有哪些扩展阅读:
简单选择排序的最优情况:
最好情况下,即待排序记录初始状态就已经是升序排列了,则不需要移动记录。
对于不稳定的排序算法,只要举出一个实例,即可说明它的不稳定性;而对于稳定的排序算法,必须对算法进行分析从而得到稳定的特性。
排序算法是否为稳定的是由具体算法决定的,不稳定的算法在某种条件下可以变为稳定的算法,而稳定的算法在某种条件下也可以变为不稳定的算法。
基数排序、冒泡排序、直接插入排序、折半插入排序、归并排序是稳定的排序算法。
堆排序、快速排序、希尔排序、直接选择排序是不稳定的排序算法。
参考资料来源:网络-简单选择排序
参考资料来源:网络-排序算法稳定性
3. 什么是稳定的排序方法
所谓稳定的排序算法就是你排序之后相同大小的数值没有发生变化,比如: 2 4 4 1 6 3 排序之后第二4的位置依然在一个4之后就是他们两个没有发生位置变化;称之为稳定;
4. 排序算法的稳定性
常用的几种排序算法中,稳定的排序有,冒泡排序,插入排序,归并排序,不稳定的排序有选择排序希尔排序,快速排序,堆排序,二叉排序树排序,等等。
5. 稳定排序算法
稳定排序算法(stable sorting algorithm)是2018年公布的计算机科学技术名词。稳定的排序算法只有直接插入排序,冒泡排序和归并排序。其余5种都是不稳定排序。关于排序的稳定性,举个例子:
一组数据排序排序前为:10,15, 5, 6(a),7 ,6(b)。
排序后:5 ,6(a), 6(b).,7, 10, 15。
排序算法的分类:
1、直接插入排序
将数组分为有序和无序两块,初始的有序区间为排序数组的第一个值,其后的为无序区间。
每次取无序区间的第一个值向前比较然后插入,插入位置以后的元素下标后移1。
最坏情况下: 时间复杂度为O(n^2) 无序的时候。
最好情况下: 时间复杂度为O(n) 有序的时候。
空间复杂的为O(1)。
越有序越快。
2、冒泡排序
冒泡排序的原理:依次比较相邻下标的两位的数值,然后进行排序,每一躺确定一个最大的数,将其放在数组最后。
冒泡排序https://blog.csdn.net/wave_xiong/article/details/102627782。
最坏情况下: 时间复杂度为O(n^2) 无序的时候。
最好情况下: 时间复杂度为O(n) 有序的时候。
6. 稳定的排序算法有哪些
1.稳定的排序
冒泡排序(bubble sort) — O(n2)
鸡尾酒排序 (Cocktail sort, 双向的冒泡排序) — O(n2)
插入排序 (insertion sort)— O(n2)
桶排序 (bucket sort)— O(n); 需要 O(k) 额外 记忆体
计数排序 (counting sort) — O(n+k); 需要 O(n+k) 额外 记忆体
归并排序 (merge sort)— O(n log n); 需要 O(n) 额外记忆体
原地归并排序 — O(n2)
二叉树排序 (Binary tree sort) — O(n log n); 需要 O(n) 额外记忆体
鸽巢排序 (Pigeonhole sort) — O(n+k); 需要 O(k) 额外记忆体
基数排序 (radix sort)— O(n·k); 需要 O(n) 额外记忆体
Gnome sort — O(n2)
Library sort — O(n log n) with high probability, 需要 (1+ε)n 额外记忆体
2.不稳定的排序
选择排序 (selection sort)— O(n2)
希尔排序 (shell sort)— O(n log n) 如果使用最佳的现在版本
Comb sort — O(n log n)
堆排序 (heapsort)— O(n log n)
Smoothsort — O(n log n)
快速排序 (quicksort)— O(n log n) 期望时间, O(n2) 最坏情况; 对于大的、乱数串行一般相信是最快的已知排序
Introsort — O(n log n)
Patience sorting — O(n log n + k) 最外情况时间, 需要 额外的 O(n + k) 空间, 也需要找到最长的递增子序列(longest increasing subsequence)
7. 面试必会八大排序算法(Python)
一、插入排序
介绍
插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据。
算法适用于少量数据的排序,时间复杂度为O(n^2)。
插入排算法是稳定的排序方法。
步骤
①从第一个元素开始,该元素可以认为已经被排序
②取出下一个元素,在已经排序的元素序列中从后向前扫描
③如果该元素(已排序)大于新元素,将该元素移到下一位置
④重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
⑤将新元素插入到该位置中
⑥重复步骤2
排序演示
算法实现
二、冒泡排序
介绍
冒泡排序(Bubble Sort)是一种简单的排序算法,时间复杂度为O(n^2)。
它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
原理
循环遍历列表,每次循环找出循环最大的元素排在后面;
需要使用嵌套循环实现:外层循环控制总循环次数,内层循环负责每轮的循环比较。
步骤
①比较相邻的元素。如果第一个比第二个大,就交换他们两个。
②对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
③针对所有的元素重复以上的步骤,除了最后一个。
④持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
算法实现:
三、快速排序
介绍
快速排序(Quicksort)是对冒泡排序的一种改进,借用了分治的思想,由C. A. R. Hoare在1962年提出。
基本思想
快速排序的基本思想是:挖坑填数 + 分治法。
首先选出一个轴值(pivot,也有叫基准的),通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
实现步骤
①从数列中挑出一个元素,称为 “基准”(pivot);
②重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边);
③对所有两个小数列重复第二步,直至各区间只有一个数。
排序演示
算法实现
四、希尔排序
介绍
希尔排序(Shell Sort)是插入排序的一种,也是缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法,时间复杂度为:O(1.3n)。
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
·插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率;
·但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位。
基本思想
①希尔排序是把记录按下标的一定量分组,对每组使用直接插入算法排序;
②随着增量逐渐减少,每组包1含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法被终止。
排序演示
算法实现
五、选择排序
介绍
选择排序(Selection sort)是一种简单直观的排序算法,时间复杂度为Ο(n2)。
基本思想
选择排序的基本思想:比较 + 交换。
第一趟,在待排序记录r1 ~ r[n]中选出最小的记录,将它与r1交换;
第二趟,在待排序记录r2 ~ r[n]中选出最小的记录,将它与r2交换;
以此类推,第 i 趟,在待排序记录ri ~ r[n]中选出最小的记录,将它与r[i]交换,使有序序列不断增长直到全部排序完毕。
排序演示
选择排序的示例动画。红色表示当前最小值,黄色表示已排序序列,蓝色表示当前位置。
算法实现
六、堆排序
介绍
堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。
利用数组的特点快速指定索引的元素。
基本思想
堆分为大根堆和小根堆,是完全二叉树。
大根堆的要求是每个节点的值不大于其父节点的值,即A[PARENT[i]] >=A[i]。
在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。
排序演示
算法实现
七、归并排序
介绍
归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
基本思想
归并排序算法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
算法思想
自上而下递归法(假如序列共有n个元素)
① 将序列每相邻两个数字进行归并操作,形成 floor(n/2)个序列,排序后每个序列包含两个元素;
② 将上述序列再次归并,形成 floor(n/4)个序列,每个序列包含四个元素;
③ 重复步骤②,直到所有元素排序完毕。
自下而上迭代法
① 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
② 设定两个指针,最初位置分别为两个已经排序序列的起始位置;
③ 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
④ 重复步骤③直到某一指针达到序列尾;
⑤ 将另一序列剩下的所有元素直接复制到合并序列尾。
排序演示
算法实现
八、基数排序
介绍
基数排序(Radix Sort)属于“分配式排序”,又称为“桶子法”。
基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m) ,其中 r 为采取的基数,而m为堆数。
在某些时候,基数排序法的效率高于其他的稳定性排序法。
基本思想
将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。
基数排序按照优先从高位或低位来排序有两种实现方案:
MSD(Most significant digital) 从最左侧高位开始进行排序。先按k1排序分组, 同一组中记录, 关键码k1相等,再对各组按k2排序分成子组, 之后, 对后面的关键码继续这样的排序分组, 直到按最次位关键码kd对各子组排序后. 再将各组连接起来,便得到一个有序序列。MSD方式适用于位数多的序列。
LSD (Least significant digital)从最右侧低位开始进行排序。先从kd开始排序,再对kd-1进行排序,依次重复,直到对k1排序后便得到一个有序序列。LSD方式适用于位数少的序列。
排序效果
算法实现
九、总结
各种排序的稳定性、时间复杂度、空间复杂度的总结:
平方阶O(n²)排序:各类简单排序:直接插入、直接选择和冒泡排序;
从时间复杂度来说:
线性对数阶O(nlog₂n)排序:快速排序、堆排序和归并排序;
O(n1+§))排序,§是介于0和1之间的常数:希尔排序 ;
线性阶O(n)排序:基数排序,此外还有桶、箱排序。
8. 什么是稳定的排序方法
所谓稳定的排序算法就是你排序之后相同大小的数值没有发生变化,比如:
2
4
4
1
6
3
排序之后第二4的位置依然在一个4之后就是他们两个没有发生位置变化;称之为稳定;
9. 数据结构里面什么是稳定的排序,什么是不稳定的排序,怎么看,什么是稳定性
就是说在配需前后,各个关键字的相对位置不变。
举个例子来说吧,假设在排序前数据排列如下:
排序前:5,6(1),1,4,3,6(2),(第一个6在第二个6之前)
排序后:1)如果排序后的结果是1,2,3,4,5,6(1),6(2)那么就说此排序算 法是稳定的,即使稳 定的排序。
2)如果排序后的结果是1,2,3,4,5,6(2),6(1),即6(1)和6(2)相比较排序前
他们的相对顺序改变了(第二个6排到第一个6之前了),那么就说这次排序是不稳定的 排序
像快速排序、希尔排序等算法都是不稳定排序算法,冒泡排序、插入排序等算法是稳定的排序算法。
希望对你有帮助哦~~
10. 数据结构的排序算法中,哪些排序是稳定的,哪些排序是不稳定的
快速排序、希尔排序、堆排序、直接选择排序不是稳定的排序算法。
基数排序、冒泡排序、直接插入排序、折半插入排序、归并排序是稳定的排序算法。