快速排序

算法之快速排序

允我心安 提交于 2019-12-28 04:07:36
快速排序 是1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称为 分治法 (Divide-and-Conquer Method)。 分治法的基本思想 : 将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。 快速排序的基本思想 : 设当前待排序的无序区为R[low..high],利用分治法可将快速排序的基本思想描述为: (1) 分解 在R[low..high]中任选一个记录作为基准(Pivot),以此基准将当前无序区划分为左、右两个较小的子区间R[low..pivotpos-1]和R[pivotpos+1..high],并使 左边子区间中所有记录的关键字均<=基准记录的关键字pivot.key,右边的子区间中所有记录的关键字均>=pivot.key,而基准记录pivot则位于正确的位置(pivotpos)上,它无须参加后续的排序。 (2) 求解 通过递归调用快速排序对左、右子区间R[low..pivotpos-1]和R[pivotpos+1..high]分别进行快速排序。 (3) 组合 因为当“求解”步骤中的两个递归调用结束时,其左、右两个子区间已有序。对快速排序而言,“组合”步骤无须做什么,可看做是空操作。 1 #include <stdio.h> 2 3 int partition(int *a,

排序05-快速排序

旧街凉风 提交于 2019-12-28 04:07:23
一)定义 快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。 (1) 分治法的基本思想 分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。 (2)快速排序的基本思想 设当前待排序的无序区为R[low..high],利用分治法可将快速排序的基本思想描述为: ①分解: 在R[low..high]中任选一个记录作为基准(Pivot),以此基准将当前无序区划分为左、右两个较小的子区间R[low..pivotpos-1)和R[pivotpos+1..high],并使左边子区间中所有记录的关键字均小于等于基准记录(不妨记为pivot)的关键字pivot.key,右边的子区间中所有记录的关键字均大于等于pivot.key,而基准记录pivot则位于正确的位置(pivotpos)上,它无须参加后续的排序。 注意: 划分的关键是要求出基准记录所在的位置pivotpos。划分的结果可以简单地表示为(注意pivot=R[pivotpos]): R[low..pivotpos-1].keys≤R[pivotpos].key≤R[pivotpos+1..high].keys 其中low≤pivotpos≤high。

图解快速排序

旧时模样 提交于 2019-12-28 04:06:52
快速排序是冒泡排序的改进版,也是最好的一种内排序,在很多面试题中都会出现,也是作为程序员必须掌握的一种排序方法。 思想:1.在待排序的元素任取一个元素作为基准(通常选第一个元素,但最的选择方法是从待排序元素中随机选取一个作为基准),称为基准元素; 2.将待排序的元素进行分区,比基准元素大的元素放在它的右边,比其小的放在它的左边; 3.对左右两个分区重复以上步骤直到所有元素都是有序的。 所以我是把快速排序联想成 东拆西补 或 西拆东补 , 一边拆一边补, 直到所有元素达到有序状态。 下面再看看示图理解下吧: 6. 对元素5两边的元素也重复以上操作,直到元素达到有序状态。 算法实现: public class QuickSort { public static void quickSort(int arr[],int _left,int _right){ int left = _left; int right = _right; int temp = 0; if(left <= right){ //待排序的元素至少有两个的情况 temp = arr[left]; //待排序的第一个元素作为基准元素 while(left != right){ //从左右两边交替扫描,直到left = right while(right > left && arr[right] >= temp)

Java快速排序算法

时光怂恿深爱的人放手 提交于 2019-12-28 03:49:04
快速排序算法思想: 快速排序(Quicksort)是对冒泡排序的一种改进。 快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 用一个算法排序图形象表示了快速排序 一趟快速排序的算法是: 1)设置两个变量i、j, 排序 开始的时候:i=0,j=N-1; 2)以第一个数组元素作为关键数据,赋值给key,即key=A[0]; 3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换; 4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换; 5)重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束) 最通俗的讲法: 取第一个数跟数组中的其他数比较,小的在左边大的在右边,就这样一直递归排序 排序的基本过程 以数组{49

冒泡排序+快速排序

爷,独闯天下 提交于 2019-12-28 03:48:54
一.冒泡排序: 外层循环控制排序躺数: n个数需要跑n-1躺, 一个数组的长度为length,那么下标为length-1,那么最大趟数为length-2,即写为<length-1 //因为比较剩下最后一个数时,无需比较。 内层循环控制每一趟的比较次数: 每一趟需要比较n-i次 /* * 冒泡排序 */ public class BubbleSort {   public static void main(String[] args) {     int[] arr={6,3,8,2,9,1};     System.out.println("排序前数组为:");     for(int num:arr){       System.out.print(num+" ");     }     for(int i=0;i<arr.length-1;i++){//外层循环控制排序趟数       for(int j=0;j<arr.length-1-i;j++){//内层循环控制每一趟排序多少次         if(arr[j]>arr[j+1]){           int temp=arr[j];           arr[j]=arr[j+1];           arr[j+1]=temp;         }       }     }     System.out

快速排序算法

本秂侑毒 提交于 2019-12-28 03:48:19
快速排序算法 想必大多数程序员接触的第一种排序算法是冒泡排序,冒泡排序的特点是:逻辑简单,实现起来也不难,但在数据量比较大的时候性能比较低。 以数字由大到小的排序为例,写一个简单的冒泡排序。 /** * 冒泡排序 * Created by Administrator on 2017/4/4. */ public class BubblingSortArithmetic { /** * 冒泡排序实现 * @param array */ public static void bubblingSort(int[] array){ int temp; for (int i = 0; i < array.length-1; i++) { for (int j = 0; j < array.length-i-1; j++) { if(array[j] > array[j+1]){ temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; } } } } } 我们看到,冒泡排序就是两个for循环嵌套,内层循环再加一个if语句做逻辑判断。 通俗点解释冒泡排序就是:外层循环控制冒泡的趟数(数组长度-1),内层循环控制一趟冒泡过程中数组相邻两个元素的比较次数及最大索引位,并且一趟冒泡把这次排序中最大的那个数放到最大索引位处。

数据结构与算法之PHP排序算法(快速排序)

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-28 03:47:08
一、基本思想 快速排序又称划分交换排序,是对冒泡排序的一种改进,亦是分而治之思想在排序算法上的典型应用。 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列的目的。 二、算法过程 1)从数列中挑出一个元素,称为“基准值”; 2)将待排序元素进行分区,比基准值小的元素放在基准值前面,比基准值大的元素放在基准值后面。分区结束后,该基准值就处于数组的中间位置; 3)对左右两个分区重复以上步骤直到所有元素都是有序的。 三、算法图解及PHP代码实现 1、替换版 上图只给出了第1趟快速排序的流程。在第1趟排序中,设置pivot=arr[i],即pivot=3。 1) 右 → 左 查找小于pivot的数:找到满足条件的数arr[j]=2,此时j=4;然后将a[j]赋值a[i],此时i=0;接着从左往右遍历。 2) 左 → 右 查找大于pivot的数:找到满足条件的数arr[i]=4,此时i=1;然后将a[i]赋值a[j],此时j=4;接着从右往左遍历。 3) 右 → 左 查找小于pivot的数:找到满足条件的数arr[j]=1,此时j=3;然后将a[j]赋值a[i],此时i=1;接着从左往右遍历。 4) 左 → 右

快速排序

[亡魂溺海] 提交于 2019-12-28 03:46:46
规则 : 快速排序是找出一个元素(理论上可以随便找一个)作为基准,然后对数组进行分区操作,使基准左边元素的值都小于基准值,基准右边的元素值都大于基准值,如此作为基准的元素调整到排序后的正确位置。递归快速排序,将其他n-1个元素也调整到排序后的正确位置。最后每个元素都是在排序后的正确位置,排序完成。 时间复杂度 : T(n)=O(nlogn). 当待排序元素基本有序是,时间复杂度变为O(N 2 ) 稳定性 : 不稳定。 1 import java.util.Arrays; 2 3 4 public class QuickSort { 5 6 /** 7 * 8 * @param args 9 * @author wangpan 10 */ 11 public static void main(String[] args) { 12 int [] a={24,12,65,34,100,11,23,76,34}; 13 System.out.println("排序前:"+Arrays.toString(a)); 14 sort(a, 0, a.length-1); 15 System.out.println("排序后:"+Arrays.toString(a)); 16 } 17 18 /** 19 * 调用该方法将待排序数组分成两部分,左边一部分数据比右边一部分数据小 20 *

快速排序

筅森魡賤 提交于 2019-12-27 00:36:01
原理 :通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归,以此达到整个数据变成有序序列。 var arr = [ 9 , 8 , 7 , 6 , 5 , 4 ] ; console . log ( quick ( arr ) ) ; function quick ( num ) { if ( num . length <= 1 ) { return num ; } var midindex = parseInt ( num . length / 2 ) ; //数组长度除二取整得到中间索引 var midnum = num . splice ( midindex , 1 ) ; //splice中为从midindex处开始删除,删除1个元素,返回值为所删除元素,及取中间元素。 var left = [ ] ; //定义两个空数组存放所分的元素 var right = [ ] ; for ( var i = 0 ; i < num . length ; i ++ ) { if ( num [ i ] < midnum ) { left . push ( num [ i ] ) ; } else { right . push ( num [ i ] ) ; } }

快速排序(交换)

不想你离开。 提交于 2019-12-26 07:13:49
基本思想 首先选一个 轴值 (即比较的基准), 通过一趟排序将待排序记录分割成独立的两部分, 前一部分记录的关键码均小于或等于轴值, 后一部分记录的关键码均大于或等于轴值, 然后分别对这两部分重复上述方法,直到整个序列有序。 关键问题 ⑴如何选择轴值? ⑵如何实现分割(称一次划分)? ⑶如何处理分割得到的两个待排序子序列? ⑷如何判别快速排序的结束? (1)解决方法: 轴值可以取记录中的任意值,一般取第一个记录作为轴值。 (2)解决方法: 设待划分的序列是r[s] ~ r[t],设参数i,j分别指向子序列左、右两端的下标s和t,令r[s]为轴值,将轴值放入r[0]中。 1、j从后向前扫描,直到r[j]<r[0],将r[j]移动到r[i]的位置,使关键码小(同轴值相比)的记录移动到前面去; 2、i从前向后扫描,直到r[i]>r[0],将r[i]移动到r[j]的位置,使关键码大(同轴值比较)的记录移动到后面去; 3、重复上述过程,直到i==j。 算法描述: int Partition(int r[ ], int first, int end) { i=first; j=end; //初始化 r[0]=r[i]; while (i<j) { while (i<j && r[0]<= r[j]) j--; //右侧扫描 if (i<j) { r[i]=r[j]; i++; /