排序算法稳定性

【排序算法】快速排序

江枫思渺然 提交于 2019-12-01 07:22:20
快速排序算法原理 快速排序的原理 :是给基准数据找其正确索引位置的过程 快速排序常用术语:基准数,标志,指针,游标(后三个术语具有相同含义) 下面结合图例来理解快速排序 1.最开始选定的基准数据为数组第一个元素8,则首先用一个临时变量去存储基准数据,即tmp=8;然后分别从数组的两端扫描数组,设两个指示标志:左标志left=0指向起始位置,右标志right=4指向数组末尾 2.从数组右边开始,right=4。如果扫描到的值大于基准数据就让right减1, 如果发现有元素比该基准数据的值小(如上图中5<=tmp),就将right=4位置的值赋值给left=0位置,。 结果如下图: 然后left++,因为left=0处的值已经小于基准数,所以接下来从left+1处继续执行算法。 3.从左往右扫描,如果扫描到的值小于基准数据就让left加1,如果发现有元素大于基准数据的值,就将left位置的值赋值给right位置的值。 左移标志继续向右动最终left=right=4 ,结果如下: 4.left=right,基准数据的正确位置已找到,接下来 将tmp中保存在基准数据存放在正确索引位置(也就是arr[left] = arr[4] = tmp = 8), 第一个基准元素完成定位,如图所示: 5.递归调用快排函数,重复执行1,2,3,4步骤,直到递归结束,完成排序。 PS:从上述1-4步骤看出,

ORACLE的ORDERBY非稳定的排序

末鹿安然 提交于 2019-12-01 03:07:09
提一个问题: oracle在order by 排序时,是稳定排序算法吗? 发现用一个type进行排序后,做分页查询,第一页的数据和第二页的数据有重复 怀疑是order by 时,两次排列的顺序不一致 看到业务描述的问题可以得到的结论order by排序不稳定,还有 第一个印象就是,type肯定是不唯一的,并且没有索引吧。 这里先科普下排序的稳定性,举个最简单的例子,1,2,3,1,4,5 排序 排序的结果是1,1,2,3,4,5,这时候观察这个1,如果第一个1还是排序前的那个1,那么算法是稳定的。也就是说相等数在排序后不发生交换。 还记得以前数据结构中的几种排序算法: 选择排序复杂度为n*n,不稳定排序, 快速排序复杂度为n*n,不稳定排序, 希尔排序复杂度为nlogn,不稳定排序, 堆排序复杂度为nlogn,不稳定排序, 冒泡排序复杂度为n*n,稳定排序, 插入排序复杂度为n*n,稳定排序, 归并排序复杂度为nlogn,稳定排序 基数排序的复杂度和位数是有关的,是稳定排序。 好了回到正题,本机测试,插入几条测试数据,表结构就两个字段,id和name,没有索引 SELECT ROWNUM,ZZ_TEST.* FROM ZZ_TEST; 1 2 test 2 2 test 3 3 test 4 4 test 5 1 test 可以看到,默认差的时候是是按照rownum排序的。

冒泡排序

一笑奈何 提交于 2019-11-30 23:30:45
一、前言 冒泡排序是一种 交换排序。 什么是交换排序呢? 答曰:两两比较待排序的关键字,并交换不满足次序要求的那对数,直到整个表都满足次序要求为止。 二、算法思想 它重复地走访要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。 这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端,故名冒泡排序。 动态效果示意图: 假设有一个大小为 N 的无序序列。以升序冒泡排序为例,冒泡排序就是要 每趟排序过程中通过两两比较相邻元素,将小的数字放到前面,大的数字放在后面。 def bubbleSort(input_list): ''' 函数说明:冒泡排序(升序) Author: www.cuijiahua.com Parameters: input_list - 待排序列表 Returns: sorted_list - 升序排序好的列表 ''' if len(input_list) == 0: return [] sorted_list = input_list for i in range(len(sorted_list) - 1): print('第%d趟排序:' % (i + 1)) for j in range(len(sorted_list) - 1): if sorted_list

牛客算法学习1

六月ゝ 毕业季﹏ 提交于 2019-11-30 06:12:38
title: 牛客算法学习part1 date: 2019-06-16 20:59:43 categories: 算法 tags: 1. 概念 1.1. 时间复杂度 1.2. 空间复杂度 1.3. 最优解 1.4. 排序的稳定性 2. 数组排序 2.1. 时间复杂度O(N^2),空间复杂度O(1) 2.1.1. 冒泡排序 2.1.2. 选择排序 2.1.3. 插入排序 2.2. 时间复杂度O(NlogN) 2.2.1. 归并排序 2.2.2. 快速排序 2.2.3. 堆排序 2.2.4. 桶排序 3. 延伸题型 3.1. 区别 3.1.1. merge与quick的区别 3.2. 归并延伸 3.2.1. 求小和 3.2.2. 降序对 3.3. 桶排序 3.3.1. 排序之后的相邻最大差值 1. 概念 1.1. 时间复杂度 概念 时间复杂度 为一个算法流程中, 常数操作数量的指标, 这个指标叫做O, big O.只要高阶项, 不要低阶项, 也不要高阶项系数, 剩下部分记为f(N), 时间复杂度为O(f(N)) 常数操作 完成操作的时间与数据量无关 例子 寻找数组(长度N)中最大值 变量max = 系统最小值, 遍历数组, 时间复杂度为O(N) 有序数组二分查找 时间复杂度为O(logN) 默认以2为底 两个有序数组寻找相同的部分, 长度为N, M 循环遍历两个数组 O(N * M)

python 十大经典排序算法

只愿长相守 提交于 2019-11-30 03:32:30
python 十大经典排序算法 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。用一张图概括: 关于时间复杂度: 平方阶 (O(n2)) 排序 各类简单排序:直接插入、直接选择和冒泡排序。 线性对数阶 (O(nlog2n)) 排序 快速排序、堆排序和归并排序。 O(n1+§)) 排序,§ 是介于 0 和 1 之间的常数。 希尔排序。 线性阶 (O(n)) 排序 基数排序,此外还有桶、箱排序。 关于稳定性: 稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序。 不是稳定的排序算法:选择排序、快速排序、希尔排序、堆排序。 名词解释: n:数据规模 k:“桶”的个数 In-place:占用常数内存,不占用额外内存 Out-place:占用额外内存 稳定性:排序后 2 个相等键值的顺序和排序之前它们的顺序相同 冒泡排序 冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成

冒泡排序及优化详解

和自甴很熟 提交于 2019-11-30 02:41:38
算法思想 #   冒泡排序属于一种典型的交换排序。   交换排序顾名思义就是通过元素的两两比较,判断是否符合要求,如过不符合就交换位置来达到排序的目的。冒泡排序名字的由来就是因为在交换过程中,类似水冒泡,小(大)的元素经过不断的交换由水底慢慢的浮到水的顶端。   冒泡排序的思想就是利用的比较交换,利用循环将第 i 小或者大的元素归位,归位操作利用的是对 n 个元素中相邻的两个进行比较,如果顺序正确就不交换,如果顺序错误就进行位置的交换。通过重复的循环访问数组,直到没有可以交换的元素,那么整个排序就已经完成了。 示例 #   我们通过一个示例来理解一下基本的冒泡排序,假设当前我们有一个数组 a,内部元素为 3,4,1,5,2,即初始状态,如下图所示。我们的目的就是通过 n 趟比较来实现有底向上从大到小的的顺序。 第一遍排序 #   我们首先进行第一遍排序,如下图所示,红色代表当前比较的元素,绿色代表已经归位的元素。   (1)比较第一个和第二个元素,4>3,交换。   (2)比较第二个和第三个元素,1<3,不交换。   (3)比较第三个和第四个元素,5>1,交换。   (4)比较第四个和第五个元素,2>1,交换。   最后,我们可以看到 1 已经位于最顶部。第一遍需要尽心四次比较才能把五个数比较完。 第二遍排序 #   第二遍排序的初始状态是第一遍排序的最终状态,即4,3,5,2,1

冒泡排序

与世无争的帅哥 提交于 2019-11-30 01:42:59
冒泡排序主要思想:两两比较待排序的关键字,并交换不满足次序要求的那对数,直到整个表都满足次序要求为止。 例如升序:就是将每个数字与其第二个数字进行比较,如果签个数字大于后一个则两个数字交换位置 java package com.rs; public class Test { public static void main(String[] args) { int[] arr = {3,2,5,6,2,7,10,9}; for (int i = 0; i < arr.length; i++) { for (int j = i+1; j < arr.length; j++) { int tmp; if (arr[i]>arr[j]) { tmp = arr[j]; arr[j] = arr[i]; arr[i] = tmp; } } } for (int i = 0; i < arr.length; i++) { System.out.print(arr[i]); } } } python(加入一个bchange,如果第一此已经是正序或者反序,则不需要进行排序) def bubbleSort(input_list): if len(input_list) == 0: return [] sorted_list = input_list for i in range(len(sorted

排序之直接插入排序学习笔记

我们两清 提交于 2019-11-30 01:38:58
每天虽然还是一如既往的早起,晚睡。但是自己好几天没有刷题, 没有看书了。每天都是在各个KTV,饭店,网吧穿梭。跟那些熟悉却略显陌生的老同学聊着自己近状······感谢老天,下了雨(估计要明天就下雪了)把我从各种酒场中救了出来。忽然感觉其实安静的学习才是一件最享受的事情。今天晚上看了一下排序,整理了一下自己的学习笔记。   插入排序(Insertion Sort)的基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子文件中的适当位置,直到全部记录插入完成为止。 直接插入排序基本思想 1.直接插入排序的基本思想 直接插入排序(Straight Insertion Sorting)的基本思想是:把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,将它插入到有序表中的适当位置,使之成为新的有序表,重复n-1次可完成排序过程。 把a[i]插入到a[0],a[1],...,a[i-1]之中的具体实施过程为:先把a[i]赋值给变量t,然后将t依次与a[i-1],a[i-2],...进行比较,将比t大的元素右移一个位置,直到发现某个j(0<=j<=i-1),使得a[j]<=t或j为(-1),把t赋值给a[j+1]. 2、第i-1趟直接插入排序:  通常将一个记录R[i](i=2,3,

八大排序算法python实现

我只是一个虾纸丫 提交于 2019-11-29 15:20:48
一、概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。 我们这里说说八大排序就是内部排序。 当n较大,则应采用时间复杂度为 O(nlog2n)的排序方法:快速排序、堆排序或归并排序序。 快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短; unsortedList=[55, 91, 63, 71, 72, 7, 74, 16, 4, 31, 100, 51, 94, 35, 49, 46, 43, 59, 18, 17] 二、 算法 实现 1.插入排序——直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。 要点:设立哨兵,作为临时存储和判断数组边界之用。 直接插入排序示例: 从后往前插入 如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序, 所以插入排序是稳定的。 (无哨兵)直接插入排序——算法的实现: def

Java实现八大排序算法

巧了我就是萌 提交于 2019-11-29 15:20:30
本文对常见的排序算法进行了总结。 常见排序算法如下: 直接插入排序 希尔排序 简单选择排序 堆排序 冒泡排序 快速排序 归并排序 基数排序 它们都属于内部排序,也就是只考虑数据量较小仅需要使用内存的排序算法,他们之间关系如下: \[ \begin{cases}内部排序 \begin{cases}插入排序\begin{cases}直接插入排序\\希尔排序\end{cases}\\选择排序\begin{cases}简单选择排序\\堆排序\end{cases}\\交换排序\begin{cases}冒泡排序\\快速排序 \end{cases}\\归并排序\\ 基数排序\end{cases}\\外部排序 \end{cases} \] \[ \left\{\begin{matrix} 内部排序\\ 外部排序 \end{matrix}\right. \] 稳定与非稳定 : 如果一个排序算法能够保留数组中重复元素的相对位置则可以被称为是 稳定 的。反之,则是 非稳定 的。 直接插入排序 基本思想 通常人们整理桥牌的方法是一张一张的来,将每一张牌插入到其他已经有序的牌中的适当位置。在计算机的实现中,为了要给插入的元素腾出空间,我们需要将其余所有元素在插入之前都向右移动一位。 算法描述 一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下: 从第一个元素开始,该元素可以认为已经被排序