快速排序

快速排序算法原理及实现(单轴快速排序、三向切分快速排序、双轴快速排序)

情到浓时终转凉″ 提交于 2019-12-28 04:10:46
1. 工作原理(定义)   快速排序(Quicksort)是对冒泡排序的一种改进。(分治法策略)   快速排序的基本思想是在待排序的n个记录中任取一个记录(通常取第一个记录)作为基准,把该记录放入适当位置后,数据序列被此记录划分成两部分,分别是比基准小和比基准大的记录;然后再对基准两边的序列用同样的策略,分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。    2. 算法步骤   实现方法两种方法:挖坑法和指针交换法   基准的选择三种方法:1.选择最左边记录 2.随机选择 3.选择平均值 2.1 挖坑法 设置两个变量i、j,排序开始的时候:i=0,j=N-1; 以第一个数组元素作为关键数据,赋值给key,即key=A[0]; 从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]的值交换; 从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]的值交换; 重复第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-完成的时候,此时令循环结束】。

快速排序(QuickSort)

谁说我不能喝 提交于 2019-12-28 04:10:34
快速排序(QuickSort) 划分的关键是要求出基准记录所在的位置pivotpos,编程时候的关键点 快速排序: 既然能把冒泡KO掉,马上就激起我们的兴趣,tnd快排咋这么快,一定要好好研究一下。 首先上图: 从图中我们可以看到: left指针,right指针,base参照数。 其实思想是蛮简单的,就是通过第一遍的遍历(让left和right指针重合)来找到数组的切割点。 第一步:首先我们从数组的left位置取出该数(20)作为基准(base)参照物。 第二步:从数组的right位置向前找,一直找到比(base)小的数, 如果找到,将此数赋给left位置(也就是将10赋给20), 此时数组为:10,40,50,10,60, left和right指针分别为前后的10。 第三步:从数组的left位置向后找,一直找到比(base)大的数, 如果找到,将此数赋给right的位置(也就是40赋给10), 此时数组为:10,40,50,40,60, left和right指针分别为前后的40。 第四步:重复“第二,第三“步骤,直到left和right指针重合, 最后将(base)插入到40的位置, 此时数组值为: 10,20,50,40,60,至此完成一次排序。 第五步:此时20已经潜入到数组的内部,20的左侧一组数都比20小,20的右侧作为一组数都比20大, 以20为切入点对左右两边数按照

(排序)快速排序QuickSort

心不动则不痛 提交于 2019-12-28 04:10:10
主要内容: 1、算法思想 2、快速排序算法 3、划分算法partition 4、快排过程图解 5、完整代码 1、算法思想 快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。 (1) 分治法的基本思想  分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。 (2)快速排序的基本思想  设当前待排序的无序区为R[low..high],利用分治法可将快速排序的基本思想描述为: ①分解Divide:   在R[low..high]中任选一个元素作为基准(Pivot),以此基准将当前无序区划分为左、右两个较小的子区间R[low..pivotpos-1)和R[pivotpos+1..high],并使左边子区间中所有记录的关键字均小于等于基准记录(不妨记为pivot)的关键字pivot.key,右边的子区间中所有记录的关键字均大于等于pivot.key,而基准记录pivot则位于正确的位置(pivotpos)上,它无须参加后续的排序。 ②求解Divide:   通过递归调用快速排序对左、右子区间R[low..pivotpos-1]和R[pivotpos+1..high]快速排序。 ③组合Conquer:

快速排序

拈花ヽ惹草 提交于 2019-12-28 04:09:58
一、思想 分治。选一个pivot,将比pivot小的元素放在左边,比pivot大的元素放在右边,对左右两个子数组递归调用QuickSort。 二、实现 int partition(int* A, int low, int high) { int pivot = A[low]; while (low < high) { while (low < high && A[high] >= pivot) { high--; } A[low] = A[high]; while (low < high && A[low] <= pivot) { low++; } A[high] = A[low]; } A[low] = pivot; return low; } void QuickSort(int* A, int low,int high) { if (low < high) { int pivotPos = partition(A, low, high); QuickSort(A, low, pivotPos - 1); QuickSort(A, pivotPos + 1, high); } } 三、性能 划分的两个子问题规模分别为0和n时,时间复杂度最坏为O(n^2); 两个子问题规模相同时,时间复杂度最好为O(nlgn),平均性能更接近最好情况。 假设输入数据的所有排列不是等概率的

[数据结构]快速排序

南笙酒味 提交于 2019-12-28 04:09:46
算法思想   快速排序是对冒泡排序的一种改进。其基本思想是基于分治法的;在待排序表L[1….n]中任取一个元素pivot作为基准,通过一趟排序将待排序表划分为独立的两部分L[1…k-1]和L[k+1…n],使得L[1….k1]中所有元素小于pivot,L[k+1….n]中所有元素大于或等于pivot,则pivot放在了其最终位置L(k)上,这个过程称作一趟快速排序。而后分别递归地对两个子表重复上述过程,直至每部分内只有一个元素或空为止,即所有元素放在了其最终位置上。   首先假设划分算法已知,记为Partition(),返回的是上述中的k,注意到L(k)已经在最终的位置,所以可以先对表进行划分,而后对两个表调用同样的排序操作。因此可以递归地调用快速排序算法进行排序,具体的程序结构如下介绍。 算法代码 void QuickSort(ElemTpye A[],int low,int high){ if(low<high){ //Partition()就是划分操作,将表A[low...high]划分为满足上述条件的两个子表 int pivotpos=Partition(A,low,high);//划分 QuickSort(A,low,pivotpos-1);//依次对两个子表进行递归排序 QuickSort(A,pivotpos+1,high); } }  

iOS 快速排序

随声附和 提交于 2019-12-28 04:09:27
一.快速排序概念及其思想 快速排序(QuickSort),又称为交换排序,是分治算法的一种,快速排序采用分治的策略。 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])

快速排序

白昼怎懂夜的黑 提交于 2019-12-28 04:09:10
快速排序 1.算法思想 快速排序是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

大话算法-排序-快速排序

心已入冬 提交于 2019-12-28 04:08:28
快速排序是一种划分交换排序 基本思想是:   1.先从数列中取出一个数作为基准数,一般是第一个数。   2.将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。   3.再对左右区间重复第二步,直到各区间只有一个数。 若序列基本有序时,蜕变成冒泡排序,最坏情况是已经排好序 平均时间复杂度O(nlogn) 快速排序采用“分而治之、各个击破”的观念,此为原地(In-place)分割版本。 快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。 步骤为:   1、从数列中挑出一个元素,称为“基准”(pivot),   2、重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任何一边)。在这个分割结束之后,该基准就处于数列的中间位置。这个称为分割(partition)操作。   3、递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。   4、递归到最底部时,数列的大小是零或一,也就是已经排序好了。这个算法一定会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。 def partaion(data, left, right): less = left - 1 #小区域是从列表初始位置前一位开始

快速排序

不问归期 提交于 2019-12-28 04:08:11
终于有时间坐下来写一写这半年学习的算法,否则又要白学了。 1.Partition函数: 快排中最重要的是划分算法Partition(A,l,r):该算法输入是数组A,以及我们在这次划分中考虑的元素的范围——从下标为l的元素考虑到下标为r的元素。假设总是选取下标为r的元素作为轴p,那么一次划分结束后,p元素左边的元素都比它小,右边的元素都比它大。例如:有数组2 3 1 3 4 2 ,选取末尾红色的2为轴,经过一次划分后数组变为2 1 2 3 4 3 ,可以看到划分后轴元素2的左边都是小于等于2的元素,右边都是大于2的元素。 记住算法中重要的变量就可以快速的写出算法,划分函数中主要有三个: i,j,p ;p就是上述说的轴元素,假设每次都选取数组最后一个元素作为轴。在划分过程中j是游标,从l遍历到r;i指向比轴p大的元素中最左边的那个,如果发现j指向的元素比轴p小了,就和i指向的元素互换,i向后移动。见下图,红色的2是选中的轴元素,i指向的3是比2大的第一个元素,当前j遍历的元素是1,比轴元素2小,所以将这个1与i指向的元素3交换,得到右边交换后的图。所以这里,我们可以这样理解i,它维护了一个大于p和小于等于p的元素的分界线,并且它指向的元素总是大于p并且“准备”与比p小(或者等于p)的元素交换的。 2.quick_sort函数 有了partition函数,快排就很容易写出来了

快速排序原理

依然范特西╮ 提交于 2019-12-28 04:08:04
原理: 快速排序也是分治法思想的一种实现,他的思路是使数组中的每个元素与基准值(Pivot,通常是数组的首个值,A[0])比较,数组中比基准值小的放在基准值的左边,形成左部;大的放在右边,形成右部;接下来将左部和右部分别递归地执行上面的过程:选基准值,小的放在左边,大的放在右边。。。直到排序结束。 步骤: 1.找基准值,设Pivot = a[0] 2.分区(Partition):比基准值小的放左边,大的放右边,基准值(Pivot)放左部与右部的之间。 3.进行左部(a[0] - a[pivot-1])的递归,以及右部(a[pivot+1] - a[n-1])的递归,重复上述步骤。 /** * Created by Administrator on 2017-05-15. */public class Test { /** * @param args */ public static void main(String[] args) { Integer[] integer = {8,12,6,9,11,16,78,2}; Test.quick(integer); for(int i : integer){ System.out.print(i+" "); } } //8 12 6 9 11 public static int getMiddle(Integer[] integer