快速排序

P1177 【模板】快速排序

China☆狼群 提交于 2020-02-07 13:21:49
题解: 这道题用传统快排(如下所示)的结果就是最后三个点TLE: 如果永远取第一个元素作为枢轴的话,在数组已经有序的情况下每次划分都将得到最坏的结果,时间复杂度退化为O(n^2)。因为其中一个子序列每次都只比原序列少一个元素,该侧的递归深度将达到最大。 #include<iostream> using namespace std; int n,a[1000001]; void swap(int &a,int &b){ int t=a; a=b; b=t; } void qsort(int l,int r)//应用二分思想 { int mid=a[(l+r)/2];//中间数 int i=l,j=r; do{ while(a[i]<mid) i++;//查找左半部分比中间数大的数 while(a[j]>mid) j--;//查找右半部分比中间数小的数 if(i<=j)//如果有一组不满足排序条件(左小右大)的数 { swap(a[i],a[j]);//交换 i++; j--; } }while(i<=j);//这里注意要有= if(l<j) qsort(l,j);//递归搜索左半部分 if(i<r) qsort(i,r);//递归搜索右半部分 } int main() { cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; qsort(1,n); for

第九届蓝桥杯B组第五题--快速排序(C语言)

谁都会走 提交于 2020-02-06 20:03:05
第九届蓝桥杯B组第五题–快速排序(C语言)(填空题) 一.比赛题目 1.题目要求 以下代码可以从数组a[]中找出第k小的元素。它使用了类似快速排序中的分治算法,期望时间复杂度是O(N)的。请仔细阅读分析源码,填写划线部分缺失的内容。 # include <stdio.h> # include <stdlib.h> int quick_select ( int a [ ] , int l , int r , int k ) { int p = rand ( ) % ( r - l + 1 ) + l ; int x = a [ p ] ; { int t = a [ p ] ; a [ p ] = a [ r ] ; a [ r ] = t ; } int i = l , j = r ; while ( i < j ) { while ( i < j && a [ i ] < x ) i ++ ; if ( i < j ) { a [ j ] = a [ i ] ; j -- ; } while ( i < j && a [ j ] > x ) j -- ; if ( i < j ) { a [ i ] = a [ j ] ; i ++ ; } } a [ i ] = x ; p = i ; if ( i - l + 1 == k ) return a [ i ] ; if ( i

超级易懂快速排序 Python

跟風遠走 提交于 2020-02-06 18:19:25
快速排序 思路 1. 找出一个枢纽节点key 2. 将数组划分成左右两部分数组,左边数组中的值都比枢纽节点的值小,右边数组中的节点的值都要key比枢纽节点key的值大 3. 对左边数组进行求解,返回排序后的数组 left_arr 4. 对右边数据进行求解,返回排序后的数组 right_arr 5. 将左边数组和右边数组以及枢纽节点进行拼接 简洁版本 class Solution(): def quick_sort(self, nums): if len(nums) == 0 or len(nums) == 1: return nums less = list() more = list() mid = list() key = nums[0] for num in nums: if num < key: less.append(num) elif num > key: more.append(num) else: mid.append(num) left_arr = self.quick_sort(less) right_arr = self.quick_sort(more) return left_arr + mid + right_arr 正常版本 class Solution_0(): def quick_sort(self, nums): if len(nums) == 0

重温快速排序(递归与非递归实现)

本小妞迷上赌 提交于 2020-02-06 10:37:10
算法基本过程 简单讲,就是 分治 。选一个基准元素,将序列分割成两部分,使得左边的都比基准小,右边的都比基准大。此时基准元素位置确定了,左右两侧也相对有序。再把左右子序列看成独立的序列,选基准,分割成左边小,右边大的两部分,一直分到无法再划分下去。 快排快在哪? 相比于冒泡排序每一轮只把一个元素冒泡到序列的一端。快排虽然每一轮也只能确定一个元素的最终位置,但它用分治的思路,每一轮使得左右两侧变得相对有序。 实现细节 基准元素的选择 一般会选择第一个元素作为基准,为了避免逆序数列的极端情况,也可以随机选择一个元素作为基准,并让基准元素和首元素交换位置 元素交换的过程 双边循环 单边循环 双边循环 //左右2个指针 //右指针开始往左移动,直到发现比pivot小的,停止移动 //左指针往右移动,直到发现比pivot大的,此时交换左右指针 //回到第二行的步骤 //最后将pivot和左子序列的最后一个元素交换 public void quickSortDual ( int [ ] arr , int left , int right ) { if ( left >= right ) return ; int pivot = arr [ left ] ; int posLeft = left + 1 ; int posRight = right ; boolean moveRight =

算法浅谈——分治算法与归并、快速排序(附代码和动图演示)

我怕爱的太早我们不能终老 提交于 2020-02-06 09:50:39
在之前的文章当中,我们通过海盗分金币问题详细讲解了递归方法。 我们可以认为在递归的过程当中,我们通过函数自己调用自己,将大问题转化成了小问题,因此简化了编码以及建模。今天这篇文章呢,就正式和大家聊一聊将大问题简化成小问题的分治算法的经典使用场景——排序。 排序算法 排序算法有很多,很多博文都有总结,号称有十大经典的排序算法。我们信手拈来就可以说上来很多,比如插入排序、选择排序、桶排序、希尔排序、快速排序、归并排序等等。老实讲这么多排序算法,但我们实际工作中并不会用到那么多,凡是高级语言都有自带的排序工具,我们直接调用就好。为了应付面试以及提升自己算法能力呢,用到的也就那么几种。今天我们来介绍一下利用分治思想实现的两种经典排序算法——归并排序与快速排序。 归并排序 我们先来讲归并排序,归并排序的思路其实很简单,说白了只有一句话:两个有序数组归并的复杂度是 \(O(n)\) 。 我们举个例子: a = [1, 4, 6] b = [2, 4, 5] c = [] 我们用i和j分别表示a和b两个数组的下标,c表示归并之后的数组,显然一开始的时候i, j = 0, 0。我们不停地比较a和b数组i和j位置大小关系,将小的那个数填入c。 填入一个数之后: i = 1 j = 0 a = [1, 4, 6] b = [2, 4, 5] c = [1] 填入两个数之后: i = 1 j = 1 a

【算法】排序算法之快速排序

巧了我就是萌 提交于 2020-02-06 08:58:41
概念 快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。 快速排序使用 分治法 (Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。 快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。 快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高!它是处理大数据最快的排序算法之一了。虽然 Worst Case 的时间复杂度达到了 O(n²),但是人家就是优秀,在大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好,可是这是为什么,在《算法艺术与信息学竞赛》上找到了满意的答案: 快速排序的最坏运行情况是 O(n²),比如说顺序数列的快排。但它的平摊期望时间是 O(nlogn),且 O(nlogn) 记号中隐含的常数因子很小,比复杂度稳定等于 O(nlogn) 的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。 算法步骤

算法之排序(中)-c语言实现

。_饼干妹妹 提交于 2020-02-06 01:20:36
文章来源:http://blog.seclibs.com/算法之排序中-c语言实现/ 上一篇文章里说了归并排序和快速排序,它们的代码实现是非常相似的,只要理解了其中的具体实现,还是比较容易写出代码的。 归并排序 代码如下,需要下载代码的请移步至文末 快速排序 代码如下,需要下载代码的请移步至文末 代码: 归并排序: GitHub 快速排序: GitHub 文章首发公众号和个人博客 公众号:无心的梦呓(wuxinmengyi) 博客:http://blog.seclibs.com/ 来源: CSDN 作者: Vesel『无心』 链接: https://blog.csdn.net/qq_18501087/article/details/104188074

数据结构排序算法-快速排序

╄→尐↘猪︶ㄣ 提交于 2020-02-05 00:23:45
快速排序 思路: 在一个序列中,随意取一个数值作为标准,将序列划分为两部分,左边一部分是小于这个标准值的,右边一部分是大于这个标准值的。 后序接着如此排序,直至序列排好序为止。 下标为0的位置是监视哨,也就是存放标准的位置。然后从j所指向的位置向前查找,只要是比49小的值就放在前面,这里27小于49,那么将27移到前面。将27存放到元素指向的位置。 接着i向后移动,38小于49,那么不变,65大于49,所以将65移动到27的位置,因为27刚才移动到了i元素的位置,现在27这个位置是空的。所以可以存放。 当 i 和 j 相等的时候,就将标准值存放在这个空的位置。 一趟快速排序就结束了。 从前往后找大的,从后往前找小的。直到 i 不小于 j 的时候。此趟快速排序结束。 Java实现代码 package com . xingyun . paixu ; /** * 快速排序 * * @author lenovo * */ public class KuaiSuPaiXu { public static void main ( String [ ] args ) { // 定义将要进行排序的序列 int [ ] stu = { 49 , 38 , 65 , 97 , 76 , 13 , 27 , 49 } ; // 调用快速排序算法 KuaiPai ( stu , 0 , stu .

python 快速排序算法

旧城冷巷雨未停 提交于 2020-02-04 11:32:34
def quicksort(nums): if len(nums) <= 1: return nums # 左子数组 less = [] # 右子数组 greater = [] # 基准数 base = nums.pop() print('sssssssss') print(base) # 对原数组进行划分 for x in nums: if x < base: less.append(x) else: greater.append(x) # 递归调用 return quicksort(less) + [base] + quicksort(greater) def main(): nums = [6,1,2,7,9,3,4,5,10,8] print(quicksort(nums)) main() 输出: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 来源: https://www.cnblogs.com/pp8080/p/12258534.html

冒泡排序和快速排序的效率比较

ぐ巨炮叔叔 提交于 2020-02-04 11:19:49
快速排序 快速排序是通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数都比另外一部分的所有数都要小,然后再按这个方法对这两部分数据分别进行排序。这里初始化i=-1,p=0,r=7,j从0至7,这里有一个循环过程,就是拿序列里面的六个元素与第六个元素(基准元素)进行比较,如果元素小于基准元素,i+=1,交换list[i]和list[j]的顺序,当j=0时,就是list[0]与list[0]置换,这里不变,但是第一个子空间已经增大了一个元素,list[0]<=list[r];当j=1时,list[1]>=list[r],这时不交换任何位置,但第二个子空间会随着j的增大而增加一个元素,这时的第三个子空间已经减少了两个元素了。依次的当j=6时,list[6]>=list[r],不交换任何位置,而第三个子空间已经没有任何元素了。 def quicksort ( list , p , r ) : if p < r : q = partion ( list , p , r ) quicksort ( list , p , q ) quicksort ( list , q + 1 , r ) def partion ( list , p , r ) : i = p - 1 for j in range ( p , r ) : if list [ j ] <= list [ r ] :