快速排序

快速排序算法

孤街浪徒 提交于 2019-12-03 11:14:25
介绍 快速排序是对冒泡排序的一种改进。 思想:将排序的数据分为两部分,一部分数据所有数据小于另一部分所有数据,然后在分别进行快速排序,排序过程可递归,从而得到有序序列。 它使用分治法(Divide and conquer)策略,把一个串行分为两个子串行。 步骤 1. 从数列中选一个元素,作为“基准”(pivot); 2. 重新排序数列,比基准小的值在左边(left),大的值在右边(right),等值随意;得到两个子数列:left、right; 3. left子数列重复1和2;right子数列重复1和2;递归。 代码 /// <summary> /// 一次排序单元,左边小,右边大 /// </summary> /// <param name="array">排序数组</param> /// <param name="left">排序起始位置</param> /// <param name="right">排序结束位置</param> /// <returns></returns> private static int SortUnit(int[] array, int left, int right) { int pivot = array[left]; while (left < right) { // 从后向前搜索比 pivot 小的值 while (array[right]

第八周

帅比萌擦擦* 提交于 2019-12-03 10:13:19
学号 2019-2020-20182321 《数据结构与面向对象程序设计》第八周学习总结 教材学习内容总结 查找中最简单的查找就是线性查找了,也就是对一列元素一个一个的向下寻找,找到了再返回,线性查找中其实可以利用哨兵法来简化线性查找的过程。 简化查找的方法有二分查找,二分查找可以极大的减小算法的时间复杂度,但是缺点是其查找的内容必须是已经排序好的,对于那种不排序的杂乱的线性集合,二分查找法不适用,必须要先排序再查找。 除了以上的两种方法,我们其实还另外学了三种,哈希线性查找、哈希链表查找、二叉树查找,他们三个的查找方法我觉得都比以上查找快得多,但是前提是其必须要按照一定的要求将其进行排序,形成一个集合。 哈希就是找出每个单个元素与所在节点的关系,利用这层关系,我们对其进行区域性查找 二叉树查找就是利用链表形成一个二叉树,比父节点大的在右边,比父节点小的在左边,查找时顺着二叉树向下查找。 排序方面,最简单的两个也是我们在c语言里学的选择排序和冒泡排序,选择排序就是找出最大或者最小的元素依次放在数列的最左边,冒泡排序是两两进行比较,找出第一轮比较和后面几轮比较次数之间的关系,其效果就像是水池里的泡泡一样,小的或者大的数字会一点一点的向最上边移动 -插入排序就是将队列里一个又一个的值,插入到已经排序的子序列,如下面序列 20 18 23 21 20 19 11 02 21 14 55

快速排序

假如想象 提交于 2019-12-03 07:33:24
算法步骤:   1.在待排序的元素任取一个元素作为基准(通常选第一个元素,但最佳的选择方法是在待排序数组中随机选取一个作为基准),成为基准元素。   2.将待排序的元素进行分区,比基准元素大的元素放在它的右边,比其小的放在它的左边。   3.对左右两个分区重复以上步骤直到所有元素都是有序的。    时间复杂度: 快速排序在最好情况下时间复杂度为O(nlogn),最坏情况下时间复杂度为O(n 2 ); 稳定性分析:   要分析稳定性,那么就需要关注快速排序中对基准元素相等的数的处理方式。在快速排序中,左右哨兵搜索时,对于相等数并不敏感,两边遇到相等数后都会选择无视,然后继续搜索下一个数,这样问题就出现了:   以基准数为第一个数为例,那么相等的数是位于基准数右边的,与原先的基准数、相等数二者之间次序相同,是稳定的;另一方面,如果左边哨兵发现了相等数,也不对其进行操作,那么相遇点肯定就在相等数的右边了,最终基准数被交换到相等数的右边,此时相等数与基准数之间的次序改变了,是不稳定的。   综上所述,快速排序是一种不稳定的排序算法。 代码实现: 第一种方法: 1 public class QuickSort { 2 public static void quickSort(int arr[],int _left,int _right){ 3 int left = _left; 4 int

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

和自甴很熟 提交于 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)时间的描述并不明显

python 实现快速排序

泪湿孤枕 提交于 2019-12-03 03:43:22
从待排序列中挑出一个元素,作为"基准"(pivot),通过一趟排序,把所有比基准值小的元素放在基准前面,所有比基准值大的元素放在基准的后面(相同的数可以到任一边),这个称为分区(partition)操作。对前后两个区间重复此操作,直到前后分区的带下是0或1结束。每一次都确定待排序列中一个元素的位置。 def QuickSort (input_list, left , right ): def Divsion (input_list, left , right ): # pivot为基准 # pivot = input_list[ left ] while left < right : while left < right and input_list[ right ] >= input_list[ left ]: right -= 1 # 找到一个元素小于基准元素,则把该元素放在前面 t=input_list[ left ] input_list[ left ] = input_list[ right ] input_list[ right ]=t while left < right and input_list[ left ] <= input_list[ right ]: left += 1 # 找到一个元素大于基准元素,则把该元素放到后面 t = input_list[

C++ 快速排序算法

匿名 (未验证) 提交于 2019-12-03 00:43:02
快速排序算法最坏的时间复杂度时o(n*n),期望的运行时间为o(nlgn)。 逻辑分析: 1 先从数组中选取一个数作为基数,可随机选择; 2 将数组中大于该基数的放在该基数右边,小于该基数的放在该基数左边; 3对左右两个数组重复第二步。 代码分析 数组a[]={2,1,4,5,3,8,7,9,0,6},该数组第一次分区时,left=0,right=10,假设随机基数为a[4]=3。 首先将a[0]和a[4]互换位置,数组a[]={3,1,4,5,2,8,7,9,6,0}。 进行第一次分区: 文章来源: C++ 快速排序算法 Like 0 Dislike 0

快速排序

匿名 (未验证) 提交于 2019-12-03 00:41:02
选择一个数字 povit = array[low] 为关键字 目的就是为了确定关键字所在最终结果中的位置 通过遍历分区,左分区小于关键字,右分区大于关键字,关键字位置确定 递归时一直都是操作的 array 数组,分区是 array 的一部分,没有将分区作为一个新数组。 分区是用 low 和 high 再加上关键字位置 index 来计算的 快速排序是不稳定的 平均: O(nlogn) 最坏: O(n2) ;数组本身有序 初始数组 var array = [49, 25, 32, 95, 64, 71, 13] 选中最低位为关键字,关键字被记录以后不再关注 array[0] 的值,最后将关键字放到居中(左边数字<关键字<右边数字)的位置,即时最终结果该元素所在位置 pivot = array[0] low = 0 high = 6 从右向左遍历,遇到比关键字小的则替换,此时 low = 1 , high = 6 , array[6] 不再被关注 while (low < high && array[high] >= pivot) { high--; } array[low] = array[high]; 从左向右遍历,遇到比关键字大的则替换,此时 low = 3 , high = 6 while (low < && array[low] <= pivot) { low++; }

快速排序算法原理及其js实现

匿名 (未验证) 提交于 2019-12-03 00:39:02
要说快排的原理,通俗点说就是把一个事情,分成很多小事情来处理,分治的思想。 在初始状态下,数字6在序列的第1位。我们的目标是将6挪到序列中间的某个位置,假设这个位置是k。现在就需要寻找这个k,并且以第k位为分界点,左边的数都小于等于6,右边的数都大于等于6。 ②首先j开始出动。因为此处设置的基准数是最左边的数,所以需要让哨兵j先出动,这一点非常重要。j一步一步地向左挪动(即j--),直到 找到一个小于6的数停下来 。接下来i再一步一步向右挪动(即i++),直到找到一个数大于6的数停下来。最后j停在了数字5面前,i停在了数字7面前。 ③现在交换i和j所指向的元素的值。交换之后的序列如下: 到此,第一次交换结束。 ④接下来开始j继续向左挪动(再友情提醒,每次必须是j先出发)。他发现了4(比基准数6要小,满足要求)之后停了下来。i也继续向右挪动的,他发现了9(比基准数6要大,满足要求)之后停了下来。此时再次进行交换,交换之后的序列如下: 第二次交换结束,“探测”继续。 ⑤j继续向左挪动,他发现了3(比基准数6要小,满足要求)之后又停了下来。i继续向右移动,糟啦!此时哨兵i和哨兵j相遇了,哨兵i和哨兵j都走到3面前。说明此时“探测”结束。我们将基准数6和3进行交换。交换之后的序列如下: 到此第一轮“探测”真正结束。此时以基准数6为分界点,6左边的数都小于等于6,6右边的数都大于等于6

快速排序(快排)

匿名 (未验证) 提交于 2019-12-03 00:37:01
快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 算法处理过程 (截图参考 坐在马桶上看算法:快速排序 ): 代码: public class QuickSort { public static void sort( int [] arr, int low, int high){ int l = low; int h = high; int tmp = 0 ; if (l <= h){ // 扫描低位标小于高位标 tmp = arr[l]; while (l != h){ // 从两边交替扫描,直到l=h while (h>l && arr[h]>tmp) h-- ; // 从右往左扫描,找到第一个比基准数据小的数,进行替换 arr[l] = arr[h]; while (l<h && arr[l]<tmp) l++ ; // 从左往右扫描,找到第一个比基准数据大的数,进行替换 arr[h] = arr[l]; } arr[h] = tmp; sort( arr, low, l -1 ); // 对基准元素左边的数据进行排序 sort( arr, h+1,

三向快速排序

匿名 (未验证) 提交于 2019-12-03 00:36:02
个人简介,并不绝对,如有错误,敬请指出,谢谢:) public static void sort( int [] a ) { a , 0, a . length - 1); private static void sort( int [] a , int left , int right ) { if ( left >= right ) return ; //当左边界大于右边界直接返回不作处理。 int v = a [ left ], le = left , index = left + 1, ri = right ; //我们拿到左边界的副本,右边界的副本,取第一个元素为比较元素,比较元素的下一个元素作为索引元素。 while ( index <= ri ) { //当索引<=右边界时进行处理 if ( a [ index ] < v ) { a , index ++, le ++); //如果遇到的元素小于比较元素的话,把这个元素与左边界互换。 //简单的理解就是把小于比较元素的那个元素,都往左边挪动,然后索引+1,表示应该比较下一个元素了。 //随后,会对以原左边界和现左边界划分的元素进行又一次三向快速排序。 else if ( a [ index ] > v ) { a , index , ri --); //如果遇到的元素大于比较元素的话,把这个元素与右边界互换。 /