排序算法稳定性

各种排序算法总结

感情迁移 提交于 2019-12-02 20:06:32
排序算法 时间复杂度(最好) 时间复杂度(最坏) 时间复杂度(平均) 空间复杂度 稳定性 冒泡排序 O(N) O(N 2 ) O(N 2 ) O(1) 稳定 选择排序 O(N 2 ) O(N 2 ) O(N 2 ) O(1) 不稳定 插入排序 O(N) O(N 2 ) O(N 2 ) O(1) 稳定 希尔排序 取决于增量序列 O(N 2 ) 取决于增量序列 O(1) 不稳定 快速排序 O(N 2 ) O(NlogN) O(NlogN) O(logN) 不稳定 归并排序 O(NlogN) O(NlogN) O(NlogN) O(N) 稳定 堆排序 O(NlogN) O(NlogN) O(NlogN) O(1) 不稳定 计数排序 桶排序 冒 泡排序 冒泡排序是不断比较相邻两个元素,并不断交换,最后把大的放到数组后面。第一趟遍历会把最大的元素放到(n-1)位置,第二趟遍历会把第二大的元素放到(n-2)的位置,以此类推。 public int[] sortArray(int[] nums) { for(int i = 0; i < nums.length - 1; i++) { boolean isSorted = true; for(int j = 0; j < nums.length - i - 1; j++){ if(nums[j] > nums[j + 1]) { swap

排序算法 之 冒泡排序 插入排序 希尔排序 堆排序

别说谁变了你拦得住时间么 提交于 2019-12-02 13:44:15
简单排序 排序算法的模板函数 void x_Sort ( ElementType A[], int N)   大多数情况下, 为简单起见,讨论都是 从小到大的整数 排序 N 是 正 整数 只讨论基于 比较 的排序(> = < 有定义) 只讨论 内部 排序 稳定 性: 任意两个相等的数据,排序前后的相对位置不发生变化 没有一种排序是任何情况下都表现最好的 冒泡排序 void Bubble_Sort ( ElementType A[], int N ) {   int flag;   for ( int P = N - 1; P >= 0; P-- ){     flag = 0;     for ( int i = 0; i < P; i++ ) { //一趟冒泡       if ( A[i] > A[i+1] ) {         Swap ( A[i], A[i+1] );         flag = 1;//标识发生了交换       }     }     if ( flag == 0 ) break; //全称无交换   } } 最好情况: 顺序 T = O( N ) 最坏情况: 逆序 T = O( N^2 ) 冒泡排序算法是稳定的排序算法。 插入排序 /**********插入排序算法***********************/ void Insertion

C++面试中的排序算法总结

梦想与她 提交于 2019-12-02 06:48:56
查找和排序算法是算法的入门知识,其经典思想可以用于很多算法当中。因为其实现代码较短,应用较常见。所以在面试中经常会问到排序算法及其相关的问题。但万变不离其宗,只要熟悉了思想,灵活运用也不是难事。一般在面试中最常考的是快速排序和归并排序,并且经常有面试官要求现场写出这两种排序的代码。对这两种排序的代码一定要信手拈来才行。还有插入排序、冒泡排序、堆排序、基数排序、桶排序等。 面试官对于这些排序可能会要求比较各自的优劣、各种算法的思想及其使用场景。还有要会分析算法的时间和空间复杂度。通常查找和排序算法的考察是面试的开始,如果这些问题回答不好,估计面试官都没有继续面试下去的兴趣都没了。所以想开个好头就要把常见的排序算法思想及其特点要熟练掌握,有必要时要熟练写出代码。 接下来我们就分析一下常见的排序算法及其使用场景。限于篇幅,某些算法的详细演示和图示请自行寻找详细的参考。 冒泡排序 冒泡排序是最简单的排序之一了,其大体思想就是通过与相邻元素的比较和交换来把小的数交换到最前面。这个过程类似于水泡向上升一样,因此而得名。举个栗子,对5,3,8,6,4这个无序序列进行冒泡排序。首先从后向前冒泡,4和6比较,把4交换到前面,序列变成5,3,8,4,6。同理4和8交换,变成5,3,4,8,6,3和4无需交换。5和3交换,变成3,5,4,8,6,3.这样一次冒泡就完了,把最小的数3排到最前面了

希尔排序(C++ & Python)

余生长醉 提交于 2019-12-02 06:48:07
希尔排序 希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进。该方法又称缩小增量排序,因DL.Shell于1959年提出而得名。 希尔排序实质上是一种分组插入方法。它的基本思想是:对于n个待排序的数列,取一个小于n的整数gap(gap被称为步长)将待排序元素分成若干个组子序列,所有距离为gap的倍数的记录放在同一个组中;然后,对各组内的元素进行直接插入排序。 这一趟排序完成之后,每一个组的元素都是有序的。然后减小gap的值,并重复执行上述的分组和排序。重复这样的操作,当gap=1时,整个数列就是有序的。 下面以数列{80,30,60,40,20,10,50,70}为例,演示它的希尔排序过程。 第1趟:(gap=4) 当gap=4时,意味着将数列分为4个组: {80,20},{30,10},{60,50},{40,70}。 对应数列: {80,30,60,40,20,10,50,70} 对这4个组分别进行排序,排序结果: {20,80},{10,30},{50,60},{40,70}。 对应数列: {20,10,50,40,80,30,60,70} 第2趟:(gap=2) 当gap=2时,意味着将数列分为2个组:{20,50,80,60}, {10,40,30,70}。 对应数列: {20,10,50,40,80,30,60,70} 注意:{20,50

排序算法之稳定性

给你一囗甜甜゛ 提交于 2019-12-02 06:14:15
稳定性 稳定性好处:1)从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用。 2)现实世界的业务需要稳定性,保证原始信息不被抹去、等值元素的相对位置不变动。 插入稳定 :想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置;如果碰见一个和插入元素相等的,将把待插入的元素放在相等元素的后面;前后顺序未改变; 冒泡稳定: 小的元素往前调或者把大的元素往后调;比较是相邻的两个元素比较,交换也发生在这两个元素之间,只有在两数不等时才可能发生交换; 归并稳定 :子序列内部的相等元素不会交换;若两个子序列中有相等元素,会把处在前面的子序列保存在结果序列的前面,保证了稳定性; 基数稳定: 是基于分配的排序,按照低位先分配、收集;再按照高位分配、收集;只有不等的元素之间才可能发生交换,依次类推,直到最高位; 选择不稳定: 在一趟选择中,被选择的最小元素min需要和当前元素交换,min出现在一个和当前元素相等的元素后面,那么交换后稳定性就可能被破坏了;举个例子,序列5 8 5 2 9,第一遍选择第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了; 快速排序不稳定: 两个方向,左边的i下标当a[i] <= a[center_index] 一直往右走,其中center_index是中枢元素的数组下标

归并排序和快速排序

删除回忆录丶 提交于 2019-12-01 17:02:57
def merge_sort(arr): if len(arr) == 1: return arr p = 0 n = len(arr) q = (p+n)//2 return merge(arr, merge_sort(arr[p:q]), merge_sort(arr[q:])) def merge(arr, arr1, arr2): temp = list() i = j = 0 for r in range(len(arr)): if i < len(arr1) and j < len(arr2): # <= 保证稳定性 if arr1[i] <= arr2[j]: temp.append(arr1[i]) i += 1 else: temp.append(arr2[j]) j += 1 else: if i < len(arr1): temp.extend(arr1[i:]) else: temp.extend(arr2[j:]) return temp def quick_sort(arr): if len(arr) <= 1: return arr privot = arr[0] larr, rarr = partition(arr[1:], privot) return quick_sort(larr) + [privot] + quick_sort(rarr)

※初赛知识总结※

大兔子大兔子 提交于 2019-12-01 16:07:21
目录 前言 排序算法的稳定性 常见的排序方法比较 前言 离初赛只有两天了,写这篇博客可能也没多大作用 边刷初赛题边记录一下坑点 就当把自己跳过的坑给后人埋上吧 祈祷我不要初赛退役(笑) 排序算法的稳定性 排序算法的稳定性是指,如果有两个元素 \(i=j\) ,排序后他们的位置关系不变 (即相同值的不同元素在排序前后相对位置不变) 而不是指时间复杂度不会退化 ! 常见的排序方法比较 冒泡排序:由于两两之间比较,前者比后者大才交换位置,所以相同大小的元素位置不会交换。是稳定的 选择排序:每次操作中会无顾忌地选择小元素交换位置,会破坏稳定性。不稳定 插入排序:从最小的序列开始,每次插到自己合适的位置,对其他元素没有影响。稳定 快速排序:很显然的不稳定排序 归并排序:合并过程中可以保证元素的位置。稳定 基数排序:按位操作的排序方式,属性各自拥有优先级。稳定 希尔排序:没详细了解过,反正是不稳定的 堆排:用堆的性质更改元素序列,过程中的旋转可能会破坏稳定性。不稳定 来源: https://www.cnblogs.com/tqr06/p/11691966.html

排序算法

隐身守侯 提交于 2019-12-01 15:34:31
说道排序,我们经常提到时间复杂度和空间复杂度,那么什么是时间复杂度什么又是空间复杂度呢? 时间复杂度:时间复杂度是指执行这个算法所需要的计算工作量 求解算法的时间复杂度的具体步骤是:   ⑴ 找出算法中的基本语句;   算法中执行次数最多的那条语句就是基本语句,通常是最内层循环的循环体。   ⑵ 计算基本语句的执行次数的数量级;   只需计算基本语句执行次数的数量级,这就意味着只要保证基本语句执行次数的函数中的最高次幂正确即可,可以忽略所有低次幂和最高次幂的系数。这样能够简化算法分析,并且使注意力集中在最重要的一点上:增长率。   ⑶ 用大Ο记号表示算法的时间性能。   将基本语句执行次数的数量级放入大Ο记号中。   如果算法中包含嵌套的循环,则基本语句通常是最内层的循环体,如果算法中包含并列的循环,则将并列循环的时间复杂度相加 空间复杂度:空间复杂度是指执行这个算法所需要的内存空间   空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度;计算机上占用内存包括   程序代码所占用的空间,输入输出数据所占用的空间,辅助变量所占用的空间这三个方面。   程序代码所占用的空间取决于算法本身的长短,输入输出数据所占用的空间取决于要解决的问题,   是通过参数表调用函数传递而来,只有辅助变量是算法运行过程中临时占用的存储空间,与空间复杂度相关;   通常来说

【初赛】

荒凉一梦 提交于 2019-12-01 07:48:27
计算机? 1944年,美籍匈牙利数学家 冯 诺依曼 提出计算机基本结构和工作方式的设想 为计算机的诞生和发展提供了理论基础 微型机主要技术指标: 字长:一直计算机能够直接处理的二进制数据的基础位数 单位为位(BIT) 主频:计算机主时钟在一秒内发出的脉冲数 很大程度上决定了计算机的运算速度 内存容量:表示计算机处理信息能力强弱的一项技术指标 单位为字节(BYTE 外存容量:一般指软盘、硬盘、光盘 计算机的特点:运算速度快 运算精度高 有记忆能力 逻辑判断能力 自动控制能力 计算机硬件由五大部分组成:运算器、控制器、存储器、输入设备、输出设备 中央处理器(CPU):由 运算器、控制器和一些寄存器 组成 ​ 运算器 进行各种 算术运算和逻辑运算 ; 控制器 是计算机的指挥系统 CPU的主要性能指标是主频和字长 存储器: ​ 内部存储器:中央处理器能直接访问的存储器称为 内部存储器 ,包括 快速缓冲存储器和主存储器 ;中央处理器不能直接访问的存储器称为 外部存储器 ,外部存储器中的信息必须调入内存后才能为中央处理器处理。 ​ 主存储器 :内存也常泛称主存,但严格上说,只有当内存中只有主存,而没有快速缓冲存储器时,才能称为主存。主存储器按读写功能,可分只读 存储器(ROM) 和随机存储器 (RAM) 两种。 ​ 外部存储器: ​ 外存储器:也称辅助存储器,一般容量较大,速度比主存较慢 ​

八大经典排序算法入门

会有一股神秘感。 提交于 2019-12-01 07:42:19
排序算法入门 在我们初学算法的时候,最先接触到的就是 排序算法 ,这些排序算法应用十分广泛,而且是很多算法的基础,可以说是每个程序员都必须得掌握的了。今天小编就来带你一举拿下经典的八大排序算法,每种算法都会有算法思想描述,动图演示,代码实现,复杂度及稳定性分析等。 0 1 冒泡排序 1. 原理 假如我们要将一个无序数列升序排列,那么冒泡排序的思想就是将“大”的元素经过交换慢慢“浮”到数列顶端,具体步骤如下: a. 从第一个元素开始,比较该元素与它的下一个元素的大小,如果第一个大于第二个就交换两个元素的位置,一直比较到序列末尾,我们称这个为一轮排序过程,此时我们可以将数组分成未排序部分和有序部分(当前只有一个最大值); b. 对数组的未排序部分执行一轮冒泡排序,最大值加入有序部分(排在数组倒数第二位); c. 继续对未排序数组执行上述操作,直到整个数组有序。 2. 演示 3. 代码实现 1 public static int[] bubbleSort(int[] array) { 2 if (array.length == 0) 3 return array; 4 for (int i = 0; i < array.length; i++){ 5 boolean isSwap = false; 6 for (int j = 0; j < array.length - 1 - i; j