快速排序

C语言:用C语言实现快速排序

白昼怎懂夜的黑 提交于 2019-12-30 13:49:35
快速排序时间复杂度为 O(nlogn) ,是数组相关的题目当中经常会用到的算法。 将数组传入函数 在C语言中,数组作为参数传递时会转换为指向数组起始地址的指针,非数组形式的数据实参均以传值形式调用。 下列两种形式的传参时等价的,他们均指向数组a的初始地址。 void test ( int a [ ] ) ; void test ( int * a ) ; 因此test中的实际上是一个指针,对 a[i] 进行操作就是对 *(a + i) 操作。 由于test中的a是一个指针,因此若在test中调用数组a,应当直接调用,而不是 &a 。 &a 实质上是指向数组a的指针的地址,调用它进行操作会出错。 错误示范: void test ( int * a ) { 语句 ; . . . test11 ( & a ) ; //假设test11已定义 . . . 语句 ; } 在main函数中调用test时,test11无法执行,因为传入它的参数是指向数组a的指针的地址。 正确调用方式: void test ( int * a ) { 语句 ; . . . test11 ( a ) ; //假设test11已定义 . . . 语句 ; } 了解上述知识点后,开始写快速排序函数。 快速排序函数: void quickSort ( int * a , int left , int right ) {

快速排序

冷暖自知 提交于 2019-12-30 10:28:52
快速排序 快速排序算法: 在数据集之中,随便选一个元素作为“基准”,不一定在中间 所有小于“基准”的元素,都移到“基准”的左边,所有大于“基准”的元素,都移到基准的右边 对“基准”左边和右边的两个子集,不断重复1.2步骤,直到所有子集剩下一个元素为止 想法:一轮排完之后6(基准)左边的数都比他小,右边的都比他大,但是两边都是无序的 要把所有比key小的数移到key左边,所以要寻找比6(基准)小的数,从j开始,从右往左找,不断递减变量j的值,找到第一个下标3的数据比6小,于是把数据3和6换一下位置,完成第一次比较 key的右边现在都比它大的了,同理看左边 上面的逻辑中,左右各执行一次比较后,i左边的数都比6小,j之后的数都比6大,但是中间的数还不确定,再将j从右向左移动(因为i和key在一起呢,所以动j不动i),找比6小的,再将i向右移动,找比6大的 结束:i,j碰头了,意味着不能再继续分组了 import java . util . Arrays ; public class test { public static void main ( String [ ] args ) { int [ ] arr = { 1 , 4 , 7 , 2 , 5 , 8 , - 4 , - 12 } ; //给定一个数组 sort ( arr , 0 , arr . length - 1 ) ;

快速排序变种实现:一次宏定义引发的熬夜事件

最后都变了- 提交于 2019-12-30 01:34:11
一、背景     睡前忽然想写两行代码练练手,想起快速排序的一种变种实现,于是写了快速排序,在理论上完全没问题的情况下测试结果却很诡异,debug半天发现是宏定义导致,作为经验教训记录下来。 二、快速排序变种实现   原理:     |_| |_| |_________________________________________|     L R unSorted ---------------------------------------------------------------------------------------------------------------------    1、取哨兵下标为low,即首元素;初始状态L和R集合都为空,L集合用来存放小于pivot的值,R集合用于存放大于pivot的值。 pivot = vector<T>& vec[low] ; mi = low; ↓mi |——| |_| |_| |_________________________________________|     L R unSorted    2、遍历初始集合,如果发现当前下标元素值大于pivot则迭代器加1,不做任何操作,效果相当于移动元素到R中。 idx |_| |__| |______________________________________

快速排序

给你一囗甜甜゛ 提交于 2019-12-29 17:44:15
最常用的排序——快速排序 假设我们现在对“6 1 2 7 9 3 4 5 10 8”这 10个数进行排序。首先在这个序列中随 便找一个数作为 基准数 (不要被这个名词吓到了,这就是一个用来参照的数,待会儿你就知 道它用来做啥了)。为了方便,就让第一个数 6 作为基准数吧。接下来,需要将这个序列中 所有比基准数大的数放在 6的右边,比基准数小的数放在 6的左边,类似下面这种排列。 3 1 2 5 4 6 9 7 10 8 在初始状态下,数字 6在序列的第 1位。我们的目标是将 6挪到序列中间的某个位置, 假设这个位置是 k。现在就需要寻找这个 k,并且以第 k位为分界点,左边的数都小于等于 6, 右边的数都大于等于 6。想一想,你有办法可以做到这点吗? 给你一个提示吧。请回忆一下冒泡排序是如何通过“交换”一步步让每个数归位的。此时你也可以通过“交换”的方法来达到目的。具体是如何一步步交换呢?方法其实很简单:分别从初始序列“6 1 2 7 9 3 4 5 10 8”两端开始“探测”。先从 右往左找一个小于 6的数,再从左往右找一个大于 6的数,然后交换它们。这里可以用两个 变量 i和 j,分别指向序列左边和右边。我们为这两个变量起个好听的名字“哨兵 i”和 “哨兵 j”。刚开始的时候让哨兵 i指向序列的左边(即 i=1),指向数字 6。让哨兵 j指向序 列的右边(即 j=10)

快速排序

旧巷老猫 提交于 2019-12-29 14:56:12
这周主要是进行python学习,也看了排序的算法知识,现在把快排的代码给大家: # include <stdio.h> int a [ 101 ] , n ; //定义全局变量 void quicksort ( int left , int right ) { int i , j , t , temp ; if ( left > right ) return ; temp = a [ left ] ; i = left ; j = right ; while ( i != j ) { //顺序重要,从右边开始 while ( a [ j ] >= temp && i < j ) j -- ; //再从左往右 while ( a [ i ] <= temp && i < j ) i ++ ; //交换两个数字位置 if ( i < j ) { t = a [ i ] ; a [ i ] = a [ j ] ; a [ j ] = t ; } } //最终将基准数归位 a [ left ] = a [ i ] ; a [ i ] = temp ; quicksort ( left , i - 1 ) ; quicksort ( i + 1 , right ) ; return ; } int main ( ) { int i , j ; scanf ( "%d" , & n ) ;

Java排序算法之快速排序

牧云@^-^@ 提交于 2019-12-28 04:12:06
一、算法原理   基于分治的思想,是冒泡排序的改进型。首先在数组中选择一个基准点(该基准点的选取可能影响快速排序的效率,后面讲解选取的方法),然后分别从数组的两端扫描数组,设两个指示标志(low指向起始位置,high指向末尾),首先从后半部分开始,如果发现有元素比该基准点的值小,就交换low和high位置的值,然后从前半部分开始扫秒,发现有元素大于基准点的值,就交换low和hi位置的值,如此往复循环,直到low>=high,然后把基准点的值放到hi这个位置。一次排序就完成了。以后采用递归的方式分别对前半部分和后半部分排序,当前半部分和后半部分均有序时该数组就自然有序了。 二、算法举例 三、算法实现   1 /** 2 * 查找出中轴(默认是最低位low)的在numbers数组排序后所在位置 3 * 4 * @param array 待查找数组 5 * @param lo 开始位置 6 * @param hi 结束位置 7 * @return 中轴所在位置 8 */ 9 static int getMiddle(int []array,int lo,int hi) { 10 //固定的切分方式 11 int key=array[lo]; 12 while(lo<hi){ 13 //从后半部分向前扫描 14 while(array[hi]>=key&&hi>lo){ 15 hi--;

常用算法之快速排序

匆匆过客 提交于 2019-12-28 04:11:51
  算法对开发的重要性不言而喻,所以准备记录一些常用算法。   本篇文章先介绍一下快速排序算法。这是在实际中最常用的一种排序算法,速度快,效率高。快速排序是非常优秀的排序算法。它是由是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,属于分治法(Divide-and-ConquerMethod)的一种。    算法思想:        1.先从数列中取出一个数作为基准数(理论上可以随便找一个)。     2.将比基准数大的数全放到它的右边,小于或等于它的数全放到它的左边。     3.再对左右区间重复第二步,直到各区间只有一个数。 举例说明:    40,20,10,70,50,60    排序过程(选取第一个元素作为基准( pivot ))   pivot[40] 40,20,10,70,50, 60 首先用40当作基准(pivot),使用low(红色表示,从左往右扫描) ,high(蓝色表示,从右向左扫描)两个指针分别从两边进行扫描,把比40小的元素和比40大的元素分开。首先比较40和60,60比40大,j左移   pivot[40] 40,20,10,70, 50 ,60 比较40和50,60比40大,high左移   pivot[40] 40,20,10, 70 ,50,60 比较40和70,70比40大,high左移   pivot[40]

排序算法:快速排序

♀尐吖头ヾ 提交于 2019-12-28 04:11:35
快速排序(Quicksort)是对冒泡排序的一种改进。 在实际中最常用的一种排序算法,速度快,效率高。 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 快速排序采用的思想是分治思想。 算法介绍: 设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。 一趟快速排序的算法是: 1)设置两个变量i、j,排序开始的时候:i=0,j=N-1; 2)以第一个数组元素作为关键数据,赋值给x,即x=rands[0]; 3)从j开始向前搜索,即由后开始向前搜索(j–),找到第一个小于x的值rands[j],将rands[j]和rands[i]互换; 4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于x的rands[i],将rands[i]和rands[j]互换; 5)重复第3、4步,直到i>=j; (3,4步中,没找到符合条件的值,即3中rands[j]不小于x,4中rands

快速排序

风格不统一 提交于 2019-12-28 04:11:11
快速排序 快速排序是对冒泡排序的一种改进。基本思想是分治法:在待排序表 L[1.....n]中任取一个元素pivot作为基准,通过一趟排序将待排序表划分为独立的两部分 L[1...k-1]和 L[k+1...n] ,使得L[1...k-1]的所有元素小于pivot,L[k+1...n]中所有元素大于pivot,则pivot放在了其最终位置L(k)上,这个过程称为一趟快速排序。而后分别递归的对两个子表重复上述过程,直至每部分内只有一个元素或空为止,即所有元素放在了其最终位置。 快速排序思路: a. 取一个元素p(第一个元素),使元素p归位; b. 列表被p分成两部分,左边都比p小,右边都比p大; c. 递归完成排序。 假设划分算法已知,记为partation(),递归的调用快排,具体结构如下: def quick_sort(data, left, right): if left < right: mid = partition(data, left, right) quick_sort(data, left, mid - 1) quick_sort(data, mid + 1, right) 可以看出快排关键在于划分操作,同时快排性能也主要取决于划分操作好坏。 对于划分算法,假设每次总是以当前表中第一个元素作为枢纽值(基准)对表进行划分,则必须将表中枢纽值大的元素向右移

排序问题之快速排序

ぐ巨炮叔叔 提交于 2019-12-28 04:10:56
排序问题 算法问题的基础问题之一,便是排序问题:   输入:n个数的一个序列,<a 1 , a 2 ,..., a n >。   输出:一个排列<a 1 ' ,a 2 ' , ... , a n' >,满足a 1 ' ≤ a 2 ' ≤... ≤ a n' 。(输出亦可为降序,左边给出的例子为升序) 一.算法描述 (1) 分治法 快速排序 使用到了分治方法(Divide and Conquer)。   Divide:将原问题分解为若干子问题,其中这些子问题的规模小于原问题的规模。   Conquer:递归地求解子问题,当子问题规模足够小时直接求解。   Merge:将子问题的解合并得到原问题的解。  (2) 快速排序的分治思想 分解: 分解待排序的n个元素序列A[p, ... q]为A[p, ... , r-1],A[r],A[r+1, ... , q],使得A[p, ... , r-1]中的所有元素都小于A[r],A[r+1, ... , q]中的所有元素都大于A[r]   解决: 递归地调用快速排序,对两个子序列A[p, ... , r-1]、A[r+1, ... , q]进行快速排序   合并: 因为子序列都是按原址排序的,不需要进行合并操作  (3) 快速排序 Partition(A, p, q): 假设我们要对一个输入规模为n的序列A[p,p+1, ... , q