快速排序

经典排序算法

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

快速排序

冷暖自知 提交于 2019-12-05 07:04:01
package sort; public class QuickSort { public static void quickSort(int[] arr,int low,int high){ int i,j,temp,t; if(low>high){ return; } i=low; j=high; //temp就是基准位 temp = arr[low]; //开始循环 while (i<j) { //先看右边,依次往左递减,基准位置右边的应该都比基准位置大,当不满足条件的时候是比基准位小的记录下来 while (temp<=arr[j]&&i<j) { j--; } //再看左边,依次往右递增,基准位左边的应该比基准位都小,当不满足条件的时候是比基准位大的记录下来 while (temp>=arr[i]&&i<j) { i++; } //进行交换 if (i<j) { t = arr[j]; arr[j] = arr[i]; arr[i] = t; } } //将基准位换到i和j相等的位置,将这个位置放在基准位 arr[low] = arr[i]; arr[i] = temp; //递归调用左半数组,进行同上的步骤 quickSort(arr, low, j-1); //递归调用右半数组,进行同上的步骤 quickSort(arr, j+1, high); } public

几种常见排序算法

不问归期 提交于 2019-12-05 06:32:46
几种常见排序算法 标签: algorithms [TOC] 本文介绍几种常见排序算法(选择排序,插入排序,希尔排序,归并排序,快速排序,堆排序),对算法的思路、性质、特点、具体步骤、java实现以及trace图解进行了全面的说明。最后对几种排序算法进行了比较和总结。 写在前面 本文所有图片均截图自coursera上普林斯顿的课程 《Algorithms, Part I》 中的Slides 相关命题的证明可参考 《算法(第4版)》 源码可在 官网 下载,也可以在我的github仓库 algorithms-learning 下载,已经使用maven构建 仓库下载: git clone git@github.com:brianway/algorithms-learning.git 基础介绍 java: Interface Comparable<T> Java中很多类已经实现了 Comparable<T> 接口,用户也可自定义类型实现该接口 total order: Antisymmetry(反对称性): if v ≤ w and w ≤ v, then v = w. Transitivity(传递性): if v ≤ w and w ≤ x, then v ≤ x. Totality: either v ≤ w or w ≤ v or both. 注意: The <= operator

(二十七)golang-排序和查找

老子叫甜甜 提交于 2019-12-05 04:58:11
排序:将一组数据,依据指定的顺序进行排列 (1)内部排序:将数据加载在内存中进行排序; 交换排序(冒泡排序,快速排序) 冒泡排序实现: 快速排序实现 (2)外部排序:数据量过大,无法全部加载到内存中,需要借助外部存储 来源: https://www.cnblogs.com/xiximayou/p/11908084.html

快速排序算法

拟墨画扇 提交于 2019-12-05 01:50:55
1. 使用策略 分治策略 2. 优点 在原址排序,空间复杂度低; 3. 复杂度 时间复杂度: 最优O(nlgn) 最坏O(n^2) 平均O(nlgn) 空间复杂度: 最优O(lgn) 最坏O(n) 平均(lgn) 4. 算法解析 关键:将数组按照某个中心值进行分割;中心值左侧均小于中心值,中心值右侧均大于中心值; 方法(partition): 1. 设两个边界值,来表示数组的索引区间;[lo, hi)=>lo=0, hi=A.length 2. 将数组最后一个值设为中心值 3. 左侧设一个遍历索引,从i=0开始遍历; 如果A[i]比中心值大,和右侧开始遍历的值交换,然后再次比较该位置的值和中心值的大小; 否则移动遍历索引,相当于将其归入已排序子数组[lo, i)。 4. 右侧设一个遍历索引j, 每次被交换后,j向前移动一位,遍历后的数组归为[j,hi-1); 5. 当i===j时,遍历结束;因为j位于第二个区间,则将其与最后的中心值交换;返回j 6. 左右两侧的子数组递归调用该方法 代码实现: function swap(A, i, j) {// 比[a,b]=[b,a]效率高 let temp = A[i]; A[i] = A[j]; A[j] = temp; } //返回中心值最后所在位置;同时已经排序 function partition(A, lo, hi) { const

数据结构与算法之美学习笔记:第十四讲

我只是一个虾纸丫 提交于 2019-12-05 00:30:27
一、课前问题 几乎所有的编程语言都会提供排序函数,比如C语言中qsort(),C++ STL中的sort()、stable_sort(),还有Java语言中的Collections.sort()。 在平时的开发中,我们也都是直接使用这些现成的函数来实现业务逻辑中的排序功能。那你知道这些排序函数是如何实现的吗?底层都利用了哪种排序算法呢? 基于这些问题,今天我们就来看排序这部分的最后一块内容:如何实现一个通用的、高性能的排序函数? 二、如何选择合适的排序算法 如果要实现一个通用的、高效率的排序函数,我们应该选择哪种排序算法?我们先回顾一下前面讲过的一种排序算法。 我们前面讲过,线性排序算法的时间复杂度比较低,适用场景比较特殊。所以如果要写一个通用的排序函数,不能选择线性排序算法。 如果对小规模数据进行排序,可以选择时间复杂度是O(n )的算法; 如果对大规模数据进⾏排序,时间复杂度是O(nlogn)的算法更加高效。 所以,为了兼顾任意规模数据的排序,一般都会首选时间复杂度是O(nlogn)的排序算法来实现排序函数。 时间复杂度是O(nlogn)的排序算法不止一个,我们已经讲过的有归并排序、快速排序,后面讲堆的时候我们还会讲到堆排序。堆排序和快速排序都有比较多的应用,比如Java语言采用堆排序实现排序函数,C语言使用快速排序实现排序函数。 不知道你有没有发现,

算法 - 快速排序 - 经典快排 | 随机快排

爱⌒轻易说出口 提交于 2019-12-04 23:33:17
经典快排 经典快排的思路是选取数组的最后一个数 x,按照 问题一 的思路把整个数组划分成 小于等于 x | 大于 x 两个部分,将 x 和 大于 x 部分数组的第一个元素交换位置。此时整个数组划分成 小于等于 x | x | 大于 x 三个部分,也就是这一次排序将 x 值排好位置。 再分别对 小于等于 x 和 大于 x 中的数组递归划分,直到划分成一个数,此时所有元素也完成排序。 按照 问题二 的思路可以对经典快排做改进,使得每次划分数组成为 小于 x | 等于 x | 大于 x 三个部分,通过这种排序方式可以一次划分多个 x 值的位置,排序效率得到提高。 但是,经典快排出现问题与 数据状况 有关。每次选择 x 值都是数组的最后一个数,如果遇到 [1,2,3,4,5] 或者 [5,4,3,2,1] 这种数组,算法时间复杂度将变成 O(n^2)。 随机快排 随机快排是经典快排的一种改进,通过生成随机下标 i,选择 a[i] 和最后一个数 x 进行交换,再使用经典快排。此时的事件就是一个概率事件,需要使用期望来估计算法的时间复杂度。 仍以 [1,2,3,4,5] 为例,经过随机快排初始变换,可以形成下列五种情况,数据状况的影响有效降低。在长期期望下,随机快排算法的时间复杂度为 O(N*logN)。由于每次划分数据都需要记录 =x 数组的下标范围,因此额外的空间复杂度为 O(logN)。

快速排序

匆匆过客 提交于 2019-12-04 18:58:40
/*--> */ /*--> */ blog_quickSort Table of Contents 1. 快排分析 与 实现 1.1. 原理 1.1.1. quick sort 最坏情况 1.1.2. quick sort 期望运行时间证明 1.2. quick sort 实现 1 快排分析 与 实现 1.1 原理 quick sort 与 merge sort 类似都是 分治策略. 都具有如下的执行时间递推关系: \(T(n) <= 2T(n/2) + cn\) quick sort在理想情况下如此. T(n) : 表示n规模上的最坏执行时间. 差异在于: quick sort 将cn花在拆分上, 而 merge sort 将cn花在合并上. merge sort 花在 将2个有序数组合并 quick sort 花在 将1个无数数组 拆分为2个无序数组. 1个无数数组中所有元素, 都比 另一个数组中元素小. merge的递推关系是确定的, 而quick sort不是, 在理想情况下与merge sort相同. merge sort需要额外内存, 而 quick sort 不需要. 1.1.1 quick sort 最坏情况 最坏情况: 选出的划分元素, 产生极端情况, 只能1个集合为空, 剩余元素全在另一个集合. 具有递推关系: \(T(n) <= T(n-1) + cn\)

astinfun

只谈情不闲聊 提交于 2019-12-04 18:39:50
快速排序算法总结 一、 思想 举例说明:对数组[2,4,9,3,6,7,1,5]进行快速排序 步骤1: 首先用2当作基准,使用i j两个指针分别从两边进行扫描,把比2小的元素和比2大的元素分开 2 2 4 9 3 6 7 1 5 首先比较2和5,5比2大,j左移 2 2 4 9 3 6 7 1 5 比较2和1,1小于2,所以把1放在2的位置 2 1 4 9 3 6 7 1 5 比较2和4,4大于2,因此将4移动到后面 2 1 4 9 3 6 7 4 5 比较2和7,2和6,2和3,2和9,全部大于2,满足条件,因此不变 经过第一轮的快速排序,元素变为下面的样子 [1] 2 [4 9 3 6 7 5] 步骤2: 分别递归排序2左边和右边的序列 思想提 大专栏 astinfun 炼 : 1.将数组a第一个元素设为key,i指向数组第一个元素,j指向数组最后一个元素 2.从右向左直到找到比key小的元素j,将j的数组值赋给i的数组值:a[i] = a[j] 3.从做向右直到找到比key大的元素i,将i的数组值赋给j的数组值:a[j] = a[i] 4.a[i] = key,此时数组a被划分为3块:比a[i]小的字数组,a[i],比a[i]大的字数组 5.分别递归i左边和右边的字数组 二、 代码 三、 性能 1.快速排序是不稳定的算法 2.快速排序交换次数较多 3.快速排序的最坏时间为O

java七大排序——6_快速排序

﹥>﹥吖頭↗ 提交于 2019-12-04 18:13:29
一、快速排序: 在待排元素中找出一个基准元素,然后比较基准元素和其他元素,以基准元素为基准,将大于准的元素的放后边,小于 基准的元素放前边。然后再对分好的左右两个小区间进行快速排序 以基准元素划分区间的方式有以下2种: 第一种: 设两个参考变量less,great,less先从第一个元素开始往后遍历,直到找到的当前元素大于基准元素。 然后让great从最后一个元素开始往前遍历,直到找到当前元素小于基准元素,交换当前less和great指向的值。 再接着从less开始,重复上述动作,遍历结束的条件是less>=great; 遍历结束后,交换当前less(或great)指向的值与基准元素的值。再进行下一次的小区间内的查找 二、图示 注意:新划分的两个区间的范围是: 第一段:原本的left到上一轮基准元素最终位置的前一位;即[left,pivotIndex-1] 第二段:上一轮基准元素最终位置的后一位到原本的right;即[pivotIndex+1,right] 最终结果: 三、代码实现 public static void quickSort ( int[] array){ int left = 0; int right = array.length - 1; quickSortInternal1(array, left, right); } public static void