排序算法稳定性

排序算法| Array.sort()算法规则

…衆ロ難τιáo~ 提交于 2019-12-04 04:35:20
1、js的Array.sort()是使用什么算法排序; 1、火狐中是“ 归并排序 ” 2、V8引擎是 “ 插入排序和快速排序结合 ”。数组长度不超过10时,使用插入排序。长度超过10使用快速排序。在数组较短时插入排序更有效率。 算法复杂度: 最好情况:O(nlogn) 最坏情况:O(nlogn) 平均情况:O(nlogn) 归并排序需要一个与原数组相同长度的数组做辅助来排序 空间复杂度:O(n) 稳定性:稳定(归并排序是稳定的排序算法, temp[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++]; 这行代码可以保证当左右两部分的值相等的时候,先复制左边的值,这样可以保证值相等的时候两个元素的相对位置不变。) 选择排序、冒泡、插入、快速、 来源: https://www.cnblogs.com/liujinyu/p/11831464.html

【算法】小规模排序

淺唱寂寞╮ 提交于 2019-12-03 18:16:22
在将排序之前,首先思考一个问题:选择排序、插入排序、冒泡排序的时间复杂度均为 o(n) ,为什么大家在讲排序的时候首先更愿意讲插入排序? 在分析一个排序算法好坏的时候,往往要考虑这么几个方面: 1.时间复杂度 考虑到时间复杂度的时候就要考虑到最好情况和最坏情况,尽可能多的有序当然是最好的情况,完全逆序则是最坏的情况,有序度不同,算法的性能也不同。 2.空间复杂度 算法的内存消耗可以通过空间复杂度来衡量。其中,原地排序算法,指的是空间复杂度 o(1)的算法。 3.排序算法的稳定性 稳定性指的是,如果待排序的序列中存在值相等的元素,经过排序以后,相等元素之间原有的先后顺序不变。 举个例子,如果现在我们要给电商交易系统的“订单”排序,订单有俩个属性,一个是下单时间,一个是订单金额。对于时间相同的订单,我们希望按照金额从小到大排序,对于金额相同的订单,我们希望按照下单时间从早到晚排序。那么我们可以按照俩个属性分别排一次续,如果是稳定的排序算法,假设第一次按时间排序,第二次按照金额排序,那么稳定算法可以保持金额相同的俩个对象,在排序后的前后顺序不变。 首先介绍一下三种排序算法: 冒泡排序 冒泡排序只会操作俩个相邻的数据,每次冒泡操作都会对相邻的俩个元素进行比较,如果不满足大小关系要求就让它俩互换。一次有效的冒泡至少会让一个元素移动到它应该在的位置,重复N次就完成了N个数据的排序工作。 实际上

数据结构与算法——常用排序算法及其Java实现

邮差的信 提交于 2019-12-03 14:01:51
冒泡排序 原理: 依次比较相邻的两个数,将小数放在前面(左边),大数放在后面(右边),就像 冒泡 一样 具体操作: 第一趟,首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后,这样第一趟下来最大的数就在最后一位了。然后还是从第一个数开始重复第一趟步骤比较,但是这次不比较最后一个数了,第二趟结束后第二大的数就在倒数第二位......以此类推,直至全部排序完成。 所有代码 在这 ,关键代码如下: private static void sort(Comparable[] a) throws IllegalAccessException, InstantiationException { Object tmp; boolean noChange = false;//用来标识输入序列的排序情况, for (int i = 0;i<a.length-1 && !noChange;i++){ noChange = true;//如果某一趟没有交换,说明数据已经排好序无需再进行接下来的排序 for (int j=0;j<a.length-1-i;j++){ if(a[j].compareTo(a[j+1])>0){ tmp = a[j]; a[j] = a[j+1]; a[j+1] =

排序算法-冒泡排序

旧时模样 提交于 2019-12-03 11:29:22
排序算法系列博客: 直接插入排序 希尔排序 简单选择排序 堆排序 冒泡排序 快速排序 归并排序 计数排序 基数排序 九大排序排序是数据结构体系中最重要的内容之一,这一块必须要非常熟练的掌握,应该做到可以立马写出每个排序的代码,有多种实现方法的必须多种都能很快写出来,当然对各个排序的性能的了解也是基础且重要的。我们先对排序这一块进行一个整体的把握。 内排序:在对待排序数据存放在内存中进行的排序过程。是我们主要讨论与学习的重点。 外排序:待排数据量太大,无法一次性将所有待排序数据放入内存中,在排序过程中需要对磁盘等外部储存器进行访问。不是我们谈论与学习的重点,但也要通过相关资料或书籍了解其基本原理。 比较排序:排序过程中需要对数据关键字进行比较。 非比较排序:排序过程中不需要对数据关键字进行比较。 排序算法的稳定性:在每一次单趟排序后,相同关键字的相对顺序不变。(后面讲到了再具体解释) 所有讲解都以升序为例(降序完全就是改个符号的问题啦),本篇先讲几个简单的,复杂些的后面每个单独写。 冒泡排序 待排序数组: 42 ,13 ,15 ,28 ,23 ,17 ,14 冒泡相对算是最简单的排序了。思想就是:冒泡,就像水中的气泡,越往上泡泡约大,每一趟排序,都确定下来一个最大值,也就是冒出一个大泡泡。太多的解释不在赘述,网上都是。看下图: 解析冒泡排序过程: 1.第一趟排序 42和13比较,42

快速排序,归并排序,堆排序的数组和单链表实现

和自甴很熟 提交于 2019-12-03 07:11:42
原文链接: https://www.cnblogs.com/DarrenChan/p/8807112.html 这三个排序的时间复杂度都是O(nlogn),所以这里放到一起说。 回到顶部 1. 快速排序 # 快速排序(英语:Quicksort),又称划分交换排序(partition-exchange sort),通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 步骤为: 从数列中挑出一个元素,称为"基准"(pivot), 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。 递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。 最优时间复杂度:O(nlogn) 最坏时间复杂度:O(n2) 稳定性:不稳定 从一开始快速排序平均需要花费O(n log n)时间的描述并不明显

算法与数据结构(11)―― 堆排序(原地排序)

匿名 (未验证) 提交于 2019-12-03 00:22:01
原地排序: 之前两种的都是从索引1开始计算的,而原地排序不需要额外的辅助空间,即不用去创造堆,那么索引从0开始的~ 注意一下 最后一个非叶子结点的索引是(count - 2)/ 2 public class HeapSort { private HeapSort() { } public static void sort(Comparable[] arr){ int n = arr.length; // 注意,此时我们的堆是从0开始索引的 // 从(最后一个元素的索引-1)/2开始 // 最后一个元素的索引 = n-1 for( int i = (n-1-1)/2 ; i >= 0 ; i -- ) shiftDown2(arr, n, i); // ---- 此时已经形成一个堆了 ---- for( int i = n-1; i > 0 ; i-- ){ swap( arr, 0, i); shiftDown2(arr, i, 0); } } // 交换堆中索引为i和j的两个元素 private static void swap(Object[] arr, int i, int j){ Object t = arr[i]; arr[i] = arr[j]; arr[j] = t; } // 原始的shiftDown过程 private static void shiftDown

排序算法

这一生的挚爱 提交于 2019-12-03 00:05:17
算法比较 稳定性 插入排序,冒泡排序,二路归并排序和基数排序是稳定的排序方法; 选择排序,希尔排序,快速排序和堆排序是不稳定的排序方法; 复杂度 排序方法 平均时间 最坏情况 辅助空间 插入排序 O(n^2) O(n^2) O(1) 希尔排序 O(nlogn) O(nlogn) O(1) 冒泡排序 O(n^2) O(n^2) O(1) 快速排序 O(nlogn) O(n^2) O(logn) 选择排序 O(n^2) O(n^2) O(1) 堆排序 O(nlogn) O(nlogn) O(1) 归并排序 O(nlogn) O(nlogn) O(n) 基数排序 O(d(n+r)) O(d(n+r)) O(r+n) 方法选择 (1) 排序数据的规模n较大,关键字元素分布比较随机,并且不要求排序稳定性时,宜选用快速排序; (2) 排序数据规模n较大,内存空间又允许,并且有排序稳定性要求,宜采用归并排序; (3) 排序数据规模n较大,元素分布可能出现升序或者逆序的情况,并且对排序的稳定性不要求,宜采用堆排序或者归并排序; (4) 排序数据规模n较小,元素基本有序,或者分布也比较随机,并且有排序稳定性要求时,宜采用插入排序; (5) 排序数据规模n较小,对排序稳定性又不做要求时,宜采用选择排序; 算法实现 插入排序 插入是个比较容易理解的排序算法,每次取下一个未排序的数

几大排序的稳定性

匿名 (未验证) 提交于 2019-12-02 23:49:02
以前看人利用口诀记忆排序的稳定性:考研好痛苦,一堆(堆排序)专业课,情绪不稳定(不稳定排序),快(快速排序)来选(选择排序)一些(希尔排序)朋友聊聊天吧,剩下的都是稳定的。 感觉不错。。。。。。 接下来是八大排序总结 : (1)冒泡排序 冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。 1 void bubbleSort(int a[], int low, int high){//[low,high) 2 while(low < (high = bubble(a, low, high)));//逐趟扫描,直至全部有序 3 } 4 5 6 7 int bubble(int a[], int low, int high){ 8 int last = low; 9 while(++low<high) 10 if(a[low-1]>a[low]){ 11 swap(a[low-1],a[low]); 12 last = low;//找到上次最后一次发生交换的位置 13 } 14 return last; 15 }/

七种经典排序算法python实现

匿名 (未验证) 提交于 2019-12-02 22:51:30
最近要考算法设计,所以把排序算法总结一下。经典的排序算法包括:冒泡排序,选择排序,插入排序,快速排序,归并排序,堆排序和希尔排序。全部程序都用python3实现,默认从小到大排序。 参考文章:https://blog.csdn.net/ls5718/article/details/51809866,博主的文章里面有演示动图,不懂的时候可以看下动图。 介绍: 让两数比较大的值一直滚动到最右侧,类似泡泡一直往上飘,每次滚动都要进行比较 思路: 临近的数字两两进行比较,按照从小到大的顺序进行交换,这样一趟过去,最大的数字就被交换到了最后一位, 然后再从头开始两两比较交换,直到导数第二位时结束 步骤: 1、比较相邻的元素,如果前一个比后一个大,就交换它们两个 2、对第0个到第n-1个数据做同样的工作,这时,最小的数就会‘浮’到数组的最左边位置 3、对所以的元素重复上面的步骤,除了单一个 4、持续每次对越来越少的元素重复上面的步骤,知道没有任何一个数字需要比较 时间复杂度: O(n**2) 如果未优化的冒泡排序,最好的情况也是O(n**2),优化后的最好情况是O(n) 具体代码: 介绍: 保持最小元素在最左侧,用最左侧的元素依次和右边的元素比较,谁小谁放在左边。 思路:每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的子序列前面,直到全部记录排序完毕 步骤:1

八大排序算法

让人想犯罪 __ 提交于 2019-12-02 20:10:24
一、直接插入排序 原理 :直接插入排序(Straight Insertion Sorting)的基本思想:在要排序的一组数中,假设前面(n-1) [n>=2] 个数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。 public void insertSort(int[] arr) { int len = arr.length; int insertNum; for(int i=1; i < len; len++) { insertNum = arr[i]; int j = i - 1; while (j >= 0 && arr[j] > insertNum) { arr[j+1] = arr[j]; j--; } arr[j+1] = insertNum; } } 二、希尔排序 针对直接插入排序的效率问题,有人对次进行了改进与升级,这就是现在的希尔排序。 希尔排序 ,也称 递减增量排序算法 ,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。 希尔排序是基于插入排序的以下两点性质而提出改进方法的: 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率 但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位 对于直接插入排序问题,数据量巨大时。 将数的个数设为n,取奇数k=n/2