快速排序

[golang] 数据结构-快速排序

落花浮王杯 提交于 2020-02-26 05:05:15
快速排序是个非常经典、高效、常用的排序算法。很多语言标准库里的排序算法都有用到它。 原理 快排原理其实比较简单,就是将原本很大的数组拆成小数组去解决问题。 要拆就得找个拆的位置。如果吧这个位置称为支点,那么快速排序问题就变成了不断的去找到拆分的支点元素位置。 通常找支点就是以某个元素为标准,通过交换元素位置把所有小于标准的元素都移到一侧,大于的移到另外一侧。移动元素的逻辑就是分别从最右侧元素向左找到比指定元素小的位置,再从最左侧开始向右找比指定元素大的位置。如果两个位置不相同就交换两个位置,在继续分表从两头相向寻找。找到合适的位置就是我们需要的支点。支点两边的元素再各自重复上面的操作,直到分拆出来的子数组只剩一个元素。分拆结束,顺序也就拍好了。 那么问题来了,以哪个元素为标准去比较呢?比如可以选第一个元素。 复杂度 理想情况下找到的支点可以把数组拆分成左右长度相近的子数组,此时时间复杂度为O(n*logn) 而最差情况则是每次找到的支点元素都在某一次,导致另一侧完全浪费,寻找支点的过程也浪费。这个时候用时会达到O(n^2)。 由于会打乱相同元素原有的顺序,所以快排也是一个不稳定排序。所以常用在普通类型数据的排序中。 代码实现 package main import ( "time" "fmt" "math/rand" ) func main() { var length = 10

快速排序模板

人走茶凉 提交于 2020-02-25 22:32:20
# include <bits/stdc++.h> using namespace std ; const int maxn = 1e5 + 5 ; int a [ maxn ] , n ; void quickSort ( int * a , int l , int r ) { if ( l >= r ) return ; int i = l , j = r , t = a [ i ] ; while ( i < j ) { while ( i < j && a [ j ] >= t ) j -- ; a [ i ] = a [ j ] ; while ( i < j && a [ i ] <= t ) i ++ ; a [ j ] = a [ i ] ; } a [ i ] = t ; quickSort ( a , l , i - 1 ) ; quickSort ( a , i + 1 , r ) ; } int main ( ) { ios :: sync_with_stdio ( false ) ; cin >> n ; for ( int i = 0 ; i < n ; i ++ ) cin >> a [ i ] ; quickSort ( a , 0 , n - 1 ) ; for ( int i = 0 ; i < n ; i ++ ) printf ( "%d "

快速排序

此生再无相见时 提交于 2020-02-25 22:09:19
蓝桥杯历年省赛真题汇总及题目详解 2018年第九届蓝桥杯省赛试题详解 标题:快速排序。 以下代码可以从数组a[]中找出第k小的元素。 它使用了类似快速排序中的分治算法,期望时间复杂度是O(N)的。 请仔细阅读分析源码,填写划线部分缺失的 # include <stdio.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 - l + 1 < k )

蓝桥 算法提高 快速排序 python

醉酒当歌 提交于 2020-02-22 12:11:16
问题描述   用递归来实现快速排序(quick sort)算法。快速排序算法的基本思路是:假设要对一个数组a进行排序,且a[0] = x。首先对数组中的元素进行调整,使x放在正确的位置上。同时,所有比x小的数都位于它的左边,所有比x大的数都位于它的右边。然后对于左、右两段区域,递归地调用快速排序算法来进行排序。   输入格式:输入只有一行,包括若干个整数(不超过10个),以0结尾。   输出格式:输出只有一行,即排序以后的结果(不包括末尾的0)。 样例输入 5 2 6 1 7 3 4 0 样例输出 1 2 3 4 5 6 7 哎 如果这个题不考算法用python实现特别简单 n = list ( map ( int , input ( ) . split ( ) ) ) n . sort ( ) print ( n [ 1 : ] ) 但是 偏偏就让你用递归 就让你找你数据结构的东西 麻里麻烦 我是先看哥的C代码 然后在转的 # include <stdio.h> int m ( int start , int end , int a [ ] ) { int key = a [ start ] ; int i = start ; int j = end ; while ( i < j ) { while ( i < j && a [ j ] >= key ) j -- ; a [

【蓝桥杯ALGO-59】快速排序 Java版

柔情痞子 提交于 2020-02-21 11:22:37
试题 算法训练 快速排序 资源限制 时间限制:1.0s 内存限制:512.0MB 问题描述   快速排序是最经常使用的一种排序方式,对于给定的n个数组成的一个数组,请使用快速排序对其进行排序。   现给定一序列,请用快速排序将其按升序排序并输出。 输入格式   第一行一个数N。   第2~N+1行每行一个数,表示给定序列。 输出格式   共N行,每行一个数,表示所求序列。 样例输入 5 1 4 2 3 4 样例输出 1 2 3 4 4 数据规模和约定   共10组数据。   对100%的数据,N<=10^5,所有数均为非负数且在int范围内。 分析 对于已经排好序,或者接近排好序的情况,会进入最差情况,时间复杂度衰退到 O(n^2),采用三数中值分割法选取分区点(pivot),避免出现时间复杂度退化到最糟糕情况。 参考: 工具类算法–快排的优化(Java) Java 代码: import java . io . * ; public class Main { private static int [ ] a ; public static void main ( String [ ] args ) throws Exception { BufferedReader in = new BufferedReader ( new InputStreamReader ( System .

快速排序与冒泡排序的实现

徘徊边缘 提交于 2020-02-21 11:17:37
冒泡排序象一个气泡从河底往上冒的过程一样,每次排序都把最大的数据放到最后,具体的第一趟冒泡排序的过程为:比较第一个数据元素x[0]与第二个数据元素x[1]的大小,若x[0]<x[1],则交换两者的值,否则什么都不做;接着跟x[2],x[3]…比较,直到x[n-1]与下x[n-2]的比较。接着第二、三…趟冒泡排序,过程与上一趟相同,只不过只需比较到比上一趟前一个位置即可。 快速排序是冒泡排序的一种改进。每趟冒泡排序只是从小于该趟的最大值的一端进行比较,而快速排序每次任取一个枢纽元(可为最大值),然后从大于和小于该枢纽元两个方向进行比较。 具体的实现代码如下所示 (代码的注释过程有快速排序的具体做法) #include<stdio.h> //冒泡排序的函数定义 void Bubble(int x[], int n) { int i, j; for(i=1;i<=n-1;i++) //排序的次数 for (j = 1; j <= n - i; j++) {//进行一次冒泡排序 if (x[j] > x[j + 1]) { x[0] = x[j + 1]; x[j + 1] = x[j]; x[j] = x[0]; } else break; } } //以下为快速排序的相关函数的定义 int Partition(int x[], int low, int high) {/

一文道破快速排序从理解到优化

本小妞迷上赌 提交于 2020-02-18 20:12:33
快速排序 快速排序(QuickSort)是对冒泡排序(BubbleSort)的一种改进。 快速排序由C. A. R. Hoare在1960年提出,这是这位图灵奖得主在很年轻的时候想出来的,XMSL。 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 其基本的编程实现,我已经在这篇文章中展示过了,各种排序算法都有—— 《基础排序算法大全(Java语言描述)》 。 快排的效率很高,对随机序列是很好使的,但也可能遇到O(N 2 )的糟糕情况。不过只要加以优化这种情况基本不可能出现。 快速排序是数据结构与算法的重要知识,是程序员和计算机专业学生必知必会的重要算法,是面试的常考重点,其性能优化也是需要思考的问题…… 总之,一定要会!很会很会! 快速排序的流程 快速排序算法通过多次比较和交换来实现排序,其排序流程如下: 首先设定一个分界值,通过该分界值将数组分成左右两部分。 将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。 然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分

快速排序——分治—day—1

十年热恋 提交于 2020-02-18 03:51:26
Method 确定分界点x: q[l], q[r] 或者 q[(l+r)/2] 或者 任意数 调整区间范围 :左端所有数 < = x; 右端所有数 >= x;(重点部分) 递归排序。 Example1 问题: 给定你一个长度为n的整数数列。 请你使用快速排序对这个数列按照从小到大进行排序。 并将排好序的数列按顺序输出。 输入格式 输入共两行,第一行包含整数 n。 第二行包含 n 个整数(所有整数均在1~1000000范围内),表示整个数列。 输出格式 输出共一行,包含 n 个整数,表示排好序的数列。 数据范围 1 <= n <= 1000000 输入样例 7 5 4 1 6 3 2 7 输出样例 1 2 3 4 5 6 7 完整代码实现: //快速排序——分治_C++_day_1_2.17 //1.确定分界点 //2.调整范围 //3.递归处理左右两端 # include <iostream> using namespace std ; const int N = 1000000 ; int n ; int q [ N ] ; void quick_sort ( int q [ ] , int l , int r ) { if ( l >= r ) return ; //只有一个数时不用排序了 //第一步 确定分界点 int x = q [ l ] , i = l - 1 , j

快速排序

大兔子大兔子 提交于 2020-02-15 08:43:45
快速排序是一种 交换排序 。 它的基本思想是:通过一趟排序将要排序的数据 分割 成独立的两部分: 分割点左边都是比它小的数,右边都是比它大的数 。 然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 基本思想: 1)选择一个基准元素 , 通常选择第一个元素或者最后一个元素, 2)通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大。 3)此时基准元素在其排好序后的正确位置 4)然后分别对这两部分记录 用同样的方法继续进行排序,直到整个序列有序。 快速排序的示例: (a)一趟排序的过程: (b)排序的全过程 核心代码 public int division( int[] list, int left, int right) { // 以最左边的数(left)为基准 int base = list[left]; while (left < right) { // 从序列右端开始,向左遍历,直到找到小于base的数 while (left < right && list[right] >= base) right--; // 找到了比base小的元素,将这个元素放到最左边的位置 list[left] = list[right]; // 从序列左端开始,向右遍历

c#快速排序

蓝咒 提交于 2020-02-11 09:55:21
using System; /* 作者:朱剑 描写:C#实现快速排序算法 创建日期:2006/05/08 */ namespace ConsoleApplication1 { class DataStructDemo { static void swap( ref int a, ref int b) { int temp; temp = a; a = b; b = temp; } static void sort( int [] arr, int left, int right) { int i,j,s; if (left < right) { i = left - 1 ; j = right + 1 ; s = arr[(i + j) / 2 ]; while ( true ) { while (arr[ ++ i] < s); while (arr[ -- j] > s); if (i >= j) break ; swap( ref arr[i], ref arr[j]); } sort(arr,left,i - 1 ); sort(arr,j + 1 ,right); } } [STAThread] static void Main( string [] args) { int [] arr = { 2 , 4 , 65 , 76 , 87 , 90 , 56 , 89 ,