排序算法稳定性

排序

不问归期 提交于 2020-01-12 13:45:39
总表 排序算法 平均复杂度 最优复杂度 最差情况的复杂度 稳定性 空间复杂 起泡排序 n2 n n2 稳定 1 插入排序 n2 n n2 稳定 插入排序 选择排序 n2 n2 n2 不稳定 1 希尔排序 n2 不稳定 1 快速排序 nlogn nlogn n2 不稳定 logn 堆排序 nlogn nlogn nlogn 不稳定 1 归并排序 nlogn nlogn nlogn 稳定 n 插入排序: 把整个序列分为有序的前半部分和无序的后半部分,每次从无序的后半部分取出第一个插入到有序部分中间 起泡排序: 每次比较相邻的两个元素,若前者较大则交换两个元素的顺序,每轮会把一个最大元素交换到最后的位置; 选择排序: 把整个序列分为有序的前半部分和无序的后半部分,每次从无序的后半部分选取最小元素插入到有序部分的末尾 快速排序: 每次以某个元素为界(一般是第一个元素)将整个序列按大小划分为两部分,然后递归地对左右两组元素做同样的事情 void quickSort ( int [ ] array , int start , int end ) { if ( start >= end ) { return ; } boolean order = true ; int i = start ; int j = end ; while ( i != j ) { if ( array [ i ] >

优先级队列与堆排序

偶尔善良 提交于 2020-01-11 04:12:32
转自:http://www.cnblogs.com/yangecnu/p/Introduce-Priority-Queue-And-Heap-Sort.html 在很多应用中,我们通常需要按照优先级情况对待处理对象进行处理,比如首先处理优先级最高的对象,然后处理次高的对象。最简单的一个例子就是,在手机上玩游戏的时候,如果有来电,那么系统应该优先处理打进来的电话。 在这种情况下,我们的数据结构应该提供两个最基本的操作,一个是返回最高优先级对象,一个是添加新的对象。这种数据结构就是优先级队列(Priority Queue) 。 本文首先介绍优先级队列的定义,有序和无序数组以及堆数据结构实现优先级队列,最后介绍了基于优先级队列的堆排序(Heap Sort) 一 定义 优先级队列和通常的栈和队列一样,只不过里面的每一个元素都有一个”优先级”,在处理的时候,首先处理优先级最高的。如果两个元素具有相同的优先级,则按照他们插入到队列中的先后顺序处理。 优先级队列可以通过链表,数组,堆或者其他数据结构实现。 二 实现 数组 最简单的优先级队列可以通过有序或者无序数组来实现,当要获取最大值的时候,对数组进行查找返回即可。代码实现起来也比较简单,这里就不列出来了。 如上图: · 如果使用无序数组,那么每一次插入的时候,直接在数组末尾插入即可,时间复杂度为O(1),但是如果要获取最大值

排序算法的指标性能比较

孤者浪人 提交于 2020-01-10 20:22:16
表一 排序方法 平均时间复杂度 最好时间复杂度 最坏时间复杂度 辅助空间 稳定性 冒泡排序 O(n 2 ) O(n) O(n 2 ) O(1) 稳定 简单选择排序 O(n 2 ) O(n 2 ) O(n 2 ) O(1) 稳定 直接插入排序 O(n 2 ) O(n) O(n 2 ) O(1) 稳定 希尔排序   O(nlogn)~O(n 2 ) O(n 1.3 ) O(n 2 ) O(1) 不稳定 堆排序 O(nlogn) O(nlogn) O(nlogn) O(1) 不稳定 归并排序 O(nlogn) O(nlogn) O(nlogn) O(n) 稳定 快速排序 O(nlogn) O(n) O(n 2 ) O(logn)~O(n) 不稳定 一,七种排序算法的性能指标说明: (1)冒泡排序:最坏的情况,即为序列处于逆序的情况,此时需要比较的次数为n(n-1)/2;最好的情况就是序列本身有序,那么需要比较的次数为n-1次,平均o(n 2 ) (2)简单选择排序:无论最好最差情况,其比较次数均为n(n-1)/2,对于交换次数而言,最好的情况,交换0次,最差的情况,交换次数为n-1次,那么综合比较和交换的次数,平均时间复杂度为o(n 2 ) (3)直接插入排序:最好的情况,即排序表本身是有序的,比较了n-1次,时间复杂度为o(n);最坏的情况,即待排序为逆序,此时需要比较(n+2)*(n

05排序之基数排序

谁说我不能喝 提交于 2020-01-07 02:04:57
基数排序 数据结构整理目录 基本介绍 1)基数排序属于 “分配式排序,又称桶子法,顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些”桶“中,达到排序的作用 2)基数排序是属于稳定性的排序,基数排序法是效率高的稳定性排序法;基数排序是经典的空间换时间的方式,占用内存很大,当对海量数据排序时,容易造成OutOfMemoryError 3)基数排序是 桶排序 的扩展 4)基数排序是这样实现的: 将整数按位数切割成不同的数字,然后按每个位数分别比较。 ;对于负数的情况,需要区别对待、 分析 基本思想 将所有待比叫数值统一为同样的数位长度,数位较短的数前面补0。然后从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列 图文解释如下 第一轮排序: (1)将每个元素的个位数取出,然后看这个数应该放在哪个对应的桶(一个于维数组) (2)按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组) 第二轮排序 (1)将每个元素的 十位数 取出,然后看这个数应该放在哪个对应的桶(一个于维数组) (2)按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组) 第三轮排序 (1)将每个元素的百位数==取出,然后看这个数应该放在哪个对应的桶(一个于维数组) (2)按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组) 小结:

希尔排序(2)

情到浓时终转凉″ 提交于 2020-01-03 05:22:46
希尔(Shell)排序又称为 缩小增量排序 ,它是一种 插入排序 。它 是直接插入排序算法的一种威力加强版 。 希尔排序的 基本思想 是: 把记录按 步长 gap 分组,对每组记录采用 直接插入排序 方法进行排序。 随着 步长逐渐减小 ,所分成的组包含的记录越来越多,当步长的值减小到 1 时,整个数据合成为一组,构成一组有序记录,则完成排序。 我们来通过演示图,更深入的理解一下这个过程。 在上面这幅图中: 初始时,有一个大小为 10 的无序序列。 在 第一趟排序中 ,我们不妨设 gap1 = N / 2 = 5,即相隔距离为 5 的元素组成一组,可以分为 5 组。 接下来,按照直接插入排序的方法对每个组进行排序。 在 第二趟排序中 ,我们把上次的 gap 缩小一半,即 gap2 = gap1 / 2 = 2 (取整数)。这样每相隔距离为 2 的元素组成一组,可以分为 2 组。 按照直接插入排序的方法对每个组进行排序。 在 第三趟排序中 ,再次把 gap 缩小一半,即gap3 = gap2 / 2 = 1。 这样相隔距离为 1 的元素组成一组,即只有一组。 按照直接插入排序的方法对每个组进行排序。此时, 排序已经结束 。 需要注意一下的是,图中有两个相等数值的元素 5 和 5 。我们可以清楚的看到,在排序过程中, 两个元素位置交换 了。 所以,希尔排序是不稳定的算法。 public

常见排序算法

旧巷老猫 提交于 2020-01-03 05:04:42
索引 1. 插入排序 1.1 直接插入 1.2 折半插入 1.3 希尔排序 2. 交换排序 2.1 冒泡排序 2.2 快速排序 3. 选择排序 3.1 直接选择 3.2 堆排序 4. 归并排序 4.1 迭代归并 总结 1. 插入排序 思想 :每步将一个待排序的对象, 按其排序码大小, 插入到前面已经排好序的一组对象的适当位置上, 直到对象全部插入为止。 1.1 直接插入 1.1.1 方法: 当插入第i (i >= 1) 个对象时, 前面的V[0], V[1], …, V[i-1]已经排好序。这时, 用V[i]的排序码依次与V[i-1], V[i-2], …的排序码顺序进行比较, 找到插入位置即将V[i]插入, 原来位置上的对象向后顺移。 具体过程: 1. 把n个待排序的元素看成为一个“有序表”和一个“无序表”; 2. 开始时“有序表”中只包含1个元素,“无序表”中包含有n-1个元素; 3. 排序过程中每次从“无序表”中取出第一个元素,依次与“有序表”元素的关键字进行比较,将该元素插入到“有序表”中的适当位置,有序表个数增加1,直到“有序表”包括所有元素。 1.1.2 实例图: 1.1.3 代码: /** * 直接插入排序:将数组从小到大排序 */ #include <iostream> using namespace std; typedef int Index;//下标的别名

wiki搬运,排序算法

天大地大妈咪最大 提交于 2020-01-03 05:02:35
稳定的排序 [ 编辑 ] 冒泡排序 (bubble sort)— {\displaystyle O(n^{2})} 插入排序 (insertion sort)— {\displaystyle O(n^{2})} 鸡尾酒排序 (cocktail sort)— {\displaystyle O(n^{2})} 桶排序 (bucket sort)— {\displaystyle O(n)} ;需要 {\displaystyle O(k)} 额外空间 计数排序 (counting sort)— {\displaystyle O(n+k)} ;需要 {\displaystyle O(n+k)} 额外空间 归并排序 (merge sort)— {\displaystyle O(n\log n)} ;需要 {\displaystyle O(n)} 额外空间 原地 归并排序 — {\displaystyle O(n\log ^{2}n)} 如果使用最佳的现在版本 二叉排序树 排序(binary tree sort)— {\displaystyle O(n\log n)} 期望时间; {\displaystyle O(n^{2})} 最坏时间;需要 {\displaystyle O(n)} 额外空间 鸽巢排序 (pigeonhole sort)— {\displaystyle O(n+k)} ;需要

python实现各种常用算法之排序算法(11)

ぐ巨炮叔叔 提交于 2020-01-01 02:46:45
python实现排序算法(三) 堆排序 堆排序(Heapsort)的基本思想:是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子节点的键值或索引总是小于(或者大于)它的父节点。 算法原理 堆排序基本思想是: 将初始待排序关键字序列(R1,R2…Rn)构建成大顶堆,此堆为初始的无序区。 将堆顶元素 R[1]与最后一个元素 R[n]交换,此时得到新的无序区(R1,R2,…Rn-1)和新的有序区(Rn),且满足 R[1,2…n-1]<=R[n]。 由于交换后新的堆顶 R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,…Rn-1)调整为新堆,然后再次将 R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2…Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为 n-1,则整个排序过程完成。 复杂度分析 最坏复杂度: 时间复杂度为 O(nlogn) 最好复杂度:时间复杂度在 O(nlogn) 平均复杂度: 时间复杂度为 O(nlogn) 算法实现 import random def heap_sort ( sequence ) : def heap_adjust ( parent ) : #左孩子 child = 2 * parent + 1 #孩子的索引值小于堆的长度 while child <

基数排序(桶排序)整理

好久不见. 提交于 2019-12-31 02:26:33
基数排序介绍 1.基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用 2.基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法 3.基数排序(Radix Sort)是桶排序的扩展 4.基数排序是1887年赫尔曼·何乐礼发明的。它是这样实现的:将整数按位数切割成不同的数字,然后按每个位数分别比较。 基数排序的基本思想 1.将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。 2.这样说明,比较难理解,下面我们看一个图文解释,理解基数排序的步骤 图解 说明 1.基数排序是对传统桶排序的扩展,速度很快。 2.基数排序是经典的空间换时间的方式,占用内存很大, 当对海量数据排序时,容易造成 OutOfMemoryError 。 3.基数排序时稳定的。[注:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的

算法总结之选择排序(Java实现)

こ雲淡風輕ζ 提交于 2019-12-29 18:34:42
算法总结之选择排序(java实现) 选择排序是一种简单直观的排序算法,他也是一种交换排序算法,和冒泡算法有一定的相似程度,可以认为选择排序是冒泡排序的一种改进。 算法描叙(以顺序为列) 在未排序的数组序列中找到最小的数据元素,存放在数组序列的起始位置。 从剩余未排序的数组元素中继续寻找最小的数据元素,然后存放到已排序序列的末尾 重复第二步,直到数组所有元素均排序完毕 算法实现 public static void selectSort ( int [ ] arr ) { int temp , min = 0 ; for ( int i = 0 ; i < arr . length - 1 ; i ++ ) { min = i ; //循环查找最小值 for ( int j = i + 1 ; j < arr . length - 1 ; j ++ ) { if ( arr [ min ] > arr [ j ] ) min = j ; } if ( min != i ) { temp = arr [ i ] ; arr [ i ] = arr [ min ] ; arr [ min ] = temp ; } } } 稳定性 当选择排序用数组实现时,是不稳定的,但是如果用链表实现选择排序,则可以达到稳定,因为实际只是发生位置了变换,并没有发生位置交换,所以相同的数字不会交换位置。