百度
360搜索
搜狗搜索

快速排序原理,快速排序在什么情况下最能发挥其长处详细介绍

本文目录一览: 快速排序的思想

快速排序所采用的思想是分治的思想。
常见的快速排序方法包括冒泡排序、选择排序、插入排序、快速排序、归并排序等。这些排序方法的原理和实现方式各不相同,但其核心思想都是通过比较和交换数据的位置来达到排序的目的。
冒泡排序是一种简单的排序方法,它的主要思想是通过不断交换相邻元素的位置来将较大的元素逐步“浮”到数列的末端,从而实现排序。选择排序则是通过不断选择数列中的最小值,并将其放到数列的起始位置,再对剩余的未排序部分进行同样的操作,从而实现排序。
插入排序则是通过将未排序元素逐个插入到已排序序列中的适当位置,从而实现排序。快速排序是一种高效的排序方法,它的核心思想是通过分治策略将待排序序列分成两个子序列,然后对子序列分别排序,最终合并成有序序列。归并排序也是一种常用的排序方法,其思想是将待排序序列分成若干个子序列,分别排序,再将已排序的子序列合并成一个有序序列。
除了上述几种排序方法外,还有一些其他的排序方法,例如希尔排序、堆排序、基数排序等。这些排序方法各具特点,适用于不同的排序场景。在实际编程中,我们需要根据具体的需求选择合适的排序方法来实现排序操作。

快速排序的原理

快速排序算法通过多次比较和交换来实现排序,其排序流程如下:?

(1)首先设定一个分界值,通过该分界值将数组分成左右两部分。?

(2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。?

(3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。?

(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。

【总的来说就是:】————先定第一个分界值,以分界值为基准,左边的是从前往后依次与分界值进行比较,直到遇见比它大的值就二者交换位置,右边的是从后往前依次与分界值进行比较,直到遇到比它小的值就二者交换位置(这只是第一趟);之后会以第一个分界值为准,在左边、右边区域各自重新设置一个分界值,两边分别都像第一趟一样去依次比较;

有一组关键字序列(41,34,53,38,26,74),采用快速排序方法由大到小进行排序

快速排序又称分区交换排序,是对冒泡排序的改进,快速排序采用的思想是分治思想。。
算法原理: (1)从待排序的n个记录中任意选取一个记录(通常选取第一个记录)为分区标准;
(2)把所有小于该排序列的记录移动到左边,把所有大于该排序码的记录移动到右边,中间放所选记录,称之为第一趟排序;
(3)然后对前后两个子序列分别重复上述过程,直到所有记录都排好序。
稳定性:不稳定排序。
时间复杂度: O(nlog2n)至O(n2),平均时间复杂度为O(nlgn)。
最好的情况:是每趟排序结束后,每次划分使两个子文件的长度大致相等,时间复杂度为O(nlog2n)。
最坏的情况:是待排序记录已经排好序,第一趟经过n-1次比较后第一个记录保持位置不变,并得到一个n-1个元素的子记录;第二趟经过n-2次比较,将第二个记录定位在原来的位置上,并得到一个包括n-2个记录的子文件,依次类推,这样总的比较次数是:
Cmax=∑i=1n?1(n?i)=n(n?1)/2=O(n2)
//a:待排序数组,low:最低位的下标,high:最高位的下标void quickSort(int a[],int low, int high){ if(low>=high) { return; } int left=low; int right=high; int key=a[left]; /*用数组的第一个记录作为分区元素*/ while(left!=right){ while(left

=key) /*从右向左扫描,找第一个码值小于key的记录,并交换到key*/ --right; a[left]=a[right]; while(left
<right&&a[left]<=key) ++left; a[right]="a[left];" *从左向右扫描,找第一个码值大于key的记录,并交换到右边* } a[left]="key;" *分区元素放到正确位置* quicksort(a,low,left-1); quicksort(a,left+1,high);}题目中对(41,34,53,38,26,74)排序
第一趟 26,34 ,53 ,38,41 ,74

26,34 , 41 ,38,53 ,74

26,34 , 38 ,41,53 ,74

这样序列就这样分割成了两部分,左边部分{26,34 , 38 } 均小于 基准值(41);右边部分 {53 ,74},均大于基准值。这样子我们就达到了分割序列的目标。在接着对子序列用同样的办法进行分割,直至子序列不超过一个元素,那么排序结束,整个序列处于有序状态。
</right&&a[left]

快速排序算法原理与实现

基本原理
从序列中任选一个数作为“基准”;所有小于“基准”的数,都挪到“基准”的左边;所有大于等于“基准”的数,都挪到“基准”的右边。
在这次移动结束之后,该“基准”就处于两个序列的中间位置,不再参与后续的排序;针对“基准”左边和右边的两个子序列,不断重复上述步骤,直到所有子序列只剩下一个数为止。
1、选择“基准”,并将其从原始数组分离
先获取基准的索引值,再使用splice数组方法取出基准值。
Tips:该实例中, 基准的索引值 = parseInt(序列长度 / 2)。
Tips:splice方法会改变原始数组。例如,arr = [1, 2, 3]; 基准索引值为1,基准值为2,原始数组变为arr = [1, 3]。
2、遍历序列,拆分序列
与“基准”比较大小,并拆分为两个子序列,小于“基准”的数存储于leftArr数组当中,大于等于“基准”的数存储于rightArr数组当中。
Tips:当然,也可以将 小于等于“基准”的数存于leftArr,大于“基准”的数存于rightArr。
由于要遍历序列,将每一个数与“基准”进行大小比较,所以,需要借助for语句来实现
3、递归调用,遍历子序列并组合子序列的结果
定义一个函数,形参用于接收数组
function quickSort(arr) { };
实现递归调用遍历子序列,用concat数组方法组合子序列的结果。
4、判断子序列的长度
递归调用的过程中,子序列的长度等于1时,则停止递归调用,返回当前数组。
扩展资料
一趟快速排序的算法是:
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,直至找到为止。
参考资料:百度百科 快速排序法
快速排序算法的原理与实现:
快速排序与归并排序已有,也使用分治思想。下面介绍下对一个典型的子数组A[p..r]进行快速排序的三步分治过程:分解:数组A[p..r]被划分为两个(可能为空)子数组A[p..q-1]和A[q+1..r],使得A[p..q-1]中的每一个元素都小于等于A[q],而A[q]也小于等于A[p..q-1]中的每个元素,其中,计算下标q也是划分过程的一部分。
解决:通过递归调用快速排序,对子数组A[p..q-1]和A[q+1..r]进行排序。
合并:因为子数组都是原址排序的,所以不需要合并操作:数组A[p..r]已经有序。
通俗点讲就是把数组根据一个参照值划分为两部分,左边部分小于等于参照值,右边部分大于等于参照值,然后再不断递归调用该方法,直到数组只有一个元素,就认为其是有序的.注意:划分过程,左边部分和右边部分可以是不均衡的。
例如:
//将数组排序成满足数组左边比中间值小,右边比中间值大的方法
int partition(int arr[], int left, int right)
{
int i = left, j = right;
int tmp;
//定义参照值为数组的中间值
int pivot = arr[(left + right) / 2];
while (i <= j) {
//当arr[i]小于参照值时,符合左边小的原则,不需调换位置,直接跳过,直到找到不满足条件的A[i]时终止该循环
while (arr[i] < pivot)i++;
//当arr[j]大于参照值时,符合右边大的原则,不需调换位置,直接跳过,直到找到不满足条件的A[j]时终止该循环
while (arr[j] > pivot)j--;
//i小于j时,完成a[i]和a[j]的交换
if (i <= j) {tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
i++;
j--;
} };
//返回的i就是满足i左边的值比i小.i右边的值比i大
return i;}
void quickSort(int arr[], int left, int right) {
int index = partition(arr, left, right);
// System.out.println("index"+index);
if (left < index - 1){quickSort(arr, left, index - 1);
// System.out.println(Arrays.toString(arr));}
if (index < right){quickSort(arr, index, right);
// System.out.println(Arrays.toString(arr));}}
@Test public void testQuickSort(){ int a[] = {222,5, 2, 4, 6, 1, 3, 11, 9, 10, 8, 7,0};quickSort(a,0,a.length - 1);
System.out.println("最终排序结果"+Arrays.toString(a));}
扩展资料:
快速排序(Quicksort)是对冒泡排序的一种改进。
快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
参考链接:百度百科-快速排序算法
1、快速排序算法的原理:想必大家都学过和用过冒泡排序,这应该是大家成为程序员道路上学的第一个算法,那么我们的快速排序算法其实是在冒泡排序的基础上的一个改进,快速排序算法是利用一趟快速排序,一趟快排一般都是取第一个数作为准基数进行排序,将一串数据分成两个部分。
第一部分都比准基数小,第二部分都比准基数大。
如:(-------第一部分------准基数------第二部分------),也就这样以准基数分成了两个部分,接下来这两个部分继续使用一趟快排(可以用递归的方法),以此类推,最后数据显示是从小到大的排列顺序。
2、快速排序步骤:
我们先建立一组数据:
(1)根据一趟快排的规则,我们先定下一个准基数,通常准基数都是数据的第一位也就是这里的数字12。
(2)然后一趟快排是先从下标6向左进行和准基数12的比较,比较完一个后,然后再从下标0向右进行和准基数12的比较。
(3)我们进行比较的规则和操作是:从下标6向左进行和准基数12的比较,只要遇到的数据小于准基数12的时候我们就将这个数和准基数12进行替换,然后再执行从下标0向右进行和准基数12的比较.
如:我们从下标6向左进行和准基数12的比较,20>12,不满足一趟快排的规则,寻找下一位,1<12,所以我们将下标0的值和下标5的值进行替换替换后的结果为:
(4)执行完上一步之后,我们再从下标0向右进行和准基数12的比较,这里的规则是只要遇到的数据大于准基数12的时候我们就将这个数和准基数12进行替换,和上面一步恰恰相反。
如:我们再从下标0向右进行和准基数12的比较,30>12,所以我们将下标1的值和下标5的值进行替换。
(5)从左到右查找和从右到左的查找,都是通过下标来查找的,只要它们两者下标不相遇就可以一直进行排序,直到相遇后第一次一趟快排结束,不过,总有一次会相遇的。好了,执行完上一步之后,基本的套路也就生成了,接下来继续执行(3),(4)步骤,直到排序完成。
第一趟排序完成的结果为:
从上面第一次一趟快排结果我们可以看出从准基数那里将数据分成的两个部分,前面那一部分,1,5,5,都比准基数要小,后面的16,30,20,则比准基数要大。但是这还不算完,我们明显的看到排序并非从小到大。所以说我们需要把这整一条数据分成1,5,5和16,30,20这两个条数据再次进行一趟快排(递归),以此类推,直到排出一条规矩的数据为止。
最后的结果为:
3、快速排序代码实现:
public class QuickSort {
public static void main(String[] args) {
int arr[] = {49、38、65、97、76、13、27、49};
quickSort(arr, 0, 7);
System.out.println(Arrays.toString(arr));
}
public static void quickSort(int[] arr, int left, int right) {
if (left < right) {
int mid = partion(arr, left, right);
quickSort(arr, 0, mid - 1);
quickSort(arr, mid + 1, right);
}
}
public static void swap(int[] arr, int l, int r) {
int tmp = arr[l];
arr[l] = arr[r];
arr[r] = tmp;
}
public static int partion(int[] arr, int left, int right) {
while (left < right) {
while (left < right && arr[left] <= arr[right]) {
right--;
}
if (left
<right){
swap(arr, left, right);

}

while (left < right && arr[left] <= arr[right]) {

left++;

}

if (left
<right){
swap(arr, left, right);

}

}

return left;

}}

扩展资料:

快速排序由冒泡排序演变而来,冒泡排序原理:

1、比较相邻的元素。如果第一个比第二个大,就交换他们两个。

2、对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。

3、针对所有的元素重复以上的步骤,除了最后一个。

4、持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

参考资料:百度百科-快速排序

快速排序的原理:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

假设要排序的数组是A[1]……A[N],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一躺快速排序。一躺快速排序的算法是:1)设置两个变量I、J,排序开始的时候I:=1,J:=N;2)以第一个数组元素作为关键数据,赋值给X,即X:=A[1];3)从J开始向前搜索,即由后开始向前搜索(J:=J-1),找到第一个小于X的值,两者交换;4)从I开始向后搜索,即由前开始向后搜索(I:=I+1),找到第一个大于X的值,两者交换;5)重复第3、4步,直到I=J。

扩展资料

与普通快排不同的是,关键数据是一段buffer,首先将之前和之后的M/2个元素读入buffer并对该buffer中的这些元素进行排序,然后从被排序数组的开头(或者结尾)读入下一个元素,假如这个元素小于buffer中最小的元素,把它写到最开头的空位上;假如这个元素大于buffer中最大的元素,则写到最后的空位上。

否则把buffer中最大或者最小的元素写入数组,并把这个元素放在buffer里。保持最大值低于这些关键数据,最小值高于这些关键数据,从而避免对已经有序的中间的数据进行重排。完成后,数组的中间空位必然空出,把这个buffer写入数组中间空位。然后递归地对外部更小的部分,循环地对其他部分进行排序。

参考资料来源:百度百科—快速排序算法

快速排序的基本原理就是每一次把一个值放到它应该的位置上,然后序列被分为两部分,这个数前一部分后一部分,再对这两部分分别进行快速排序即可。

如此递归下去,但是对于基本有序的数列,你就不要快排了,那样效率会很低。

扩展资料:

算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。

如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间、空间或效率来完成同样的任务。一个算法的优劣可以用空间复杂度与时间复杂度来衡量。

算法中的指令描述的是一个计算,当其运行时能从一个初始状态和(可能为空的)初始输入开始,经过一系列有限而清晰定义的状态,最终产生输出并停止于一个终态。一个状态到另一个状态的转移不一定是确定的。随机化算法在内的一些算法,包含了一些随机输入。

形式化算法的概念部分源自尝试解决希尔伯特提出的判定问题,并在其后尝试定义有效计算性或者有效方法中成形。

这些尝试包括库尔特·哥德尔、Jacques Herbrand和斯蒂芬·科尔·克莱尼分别于1930年、1934年和1935年提出的递归函数,阿隆佐·邱奇于1936年提出的λ演算,1936年Emil Leon Post的Formulation 1和艾伦·图灵1937年提出的图灵机。即使在当前,依然常有直觉想法难以定义为形式化算法的情况。

参考资料:百度百科-算法

快速排序的基本思想就是从一个数组中任意挑选一个元素(通常来说会选择最左边的元素)作为中轴元素,将剩下的元素以中轴元素作为比较的标准,将小于等于中轴元素的放到中轴元素的左边,将大于中轴元素的放到中轴元素的右边。

然后以当前中轴元素的位置为界,将左半部分子数组和右半部分子数组看成两个新的数组,重复上述操作,直到子数组的元素个数小于等于1(因为一个元素的数组必定是有序的)。

以下的代码中会常常使用交换数组中两个元素值的Swap方法,其代码如下

public static void Swap(int[] A, int i, int j){

int tmp;

tmp = A[i];

A[i] = A[j];

A[j] = tmp;

扩展资料:

快速排序算法 的基本思想是:将所要进行排序的数分为左右两个部分,其中一部分的所有数据都比另外一 部分的数据小,然后将所分得的两部分数据进行同样的划分,重复执行以上的划分操作,直 到所有要进行排序的数据变为有序为止。

定义两个变量low和high,将low、high分别设置为要进行排序的序列的起始元素和最后一个元素的下标。第一次,low和high的取值分别为0和n-1,接下来的每次取值由划分得到的序列起始元素和最后一个元素的下标来决定。

定义一个变量key,接下来以key的取值为基准将数组A划分为左右两个部分,通 常,key值为要进行排序序列的第一个元素值。第一次的取值为A[0],以后毎次取值由要划 分序列的起始元素决定。

从high所指向的数组元素开始向左扫描,扫描的同时将下标为high的数组元素依次与划分基准值key进行比较操作,直到high不大于low或找到第一个小于基准值key的数组元素,然后将该值赋值给low所指向的数组元素,同时将low右移一个位置。

如果low依然小于high,那么由low所指向的数组元素开始向右扫描,扫描的同时将下标为low的数组元素值依次与划分的基准值key进行比较操作,直到low不小于high或找到第一个大于基准值key的数组元素,然后将该值赋给high所指向的数组元素,同时将high左移一个位置。

重复步骤(3) (4),直到low的植不小于high为止,这时成功划分后得到的左右两部分分别为A[low……pos-1]和A[pos+1……high],其中,pos下标所对应的数组元素的值就是进行划分的基准值key,所以在划分结束时还要将下标为pos的数组元素赋值 为 key。

参考资料:快速排序算法_百度百科
</right){
</right){

阅读更多 >>>  什么叫表格数据排序不对

C语言中快速排序法的原理及应用

49 38 65 97 76 13 27 50 按非降序排,
用快速排序实现
解释:用每次取的数据作为分界点,在这之内分成2块
先和最后面的数据比较,当大于时就互换位置,在和前面的数据比较
设置low 和high个指针先与high(也就是最后一个关键字比较)大于就互换位置否则就不换指导换了一次位置后改变high的位置,在与low比较小于就互换直到交换就重置low,在high就这样循环,直到high=low的时候就完成了一次
再在分开的2个区内用同样的方法比较
例如:
先去49 把数据分成 27 38 13 49 76 97 65 50
在取27 ,用相同的方法把 27 38 13排
取76 把76 97 65 50排
取49 先和50比较 小于50 在和27比较,大于27就互换位置
27 38 65 97 76 13 49 50
继续拿49 先和38比较大于就不换 在和65 小于就换位置
27 38 49 97 76 13 65 50
在拿49与13比较,大于就换
27 38 13 97 76 49 65 50
再拿65与97 小于换
27 38 13 49 76 97 65 60
再拿49与76比较,小于不换
一趟后: 27 38 13 49 76 97 65 60
继续;
蛋疼,擦,太难的表达出来了
49 38 65 97 76 13 27 50 按非降序排,
用快速排序实现
解释:用每次取的数据作为分界点,在这之内分成2块
先和最后面的数据比较,当大于时就互换位置,在和前面的数据比较
设置low 和high个指针先与high(也就是最后一个关键字比较)大于就互换位置否则就不换指导换了一次位置后改变high的位置,在与low比较小于就互换直到交换就重置low,在high就这样循环,直到high=low的时候就完成了一次
再在分开的2个区内用同样的方法比较
例如:
先去49 把数据分成 27 38 13 49 76 97 65 50
在取27 ,用相同的方法把 27 38 13排
取76 把76 97 65 50排
取49 先和50比较 小于50 在和27比较,大于27就互换位置
27 38 65 97 76 13 49 50
继续拿49 先和38比较大于就不换 在和65 小于就换位置
27 38 49 97 76 13 65 50
在拿49与13比较,大于就换
27 38 13 97 76 49 65 50
再拿65与97 小于换
27 38 13 49 76 97 65 60
再拿49与76比较,小于不换
一趟后: 27 38 13 49 76 97 65 60
继续; \
  “快速排序法”使用的是递归原理,下面我结合一个例子来说明“快速排序法”的原理。首先给出一个数组{53,12,98,63,18,72,80,46, 32,21},先找到第一个数--53,把它作为中间值,也就是说,要把53放在一个位置,使得它左边的值比它小,右边的值比它大。{21,12,32, 46,18,53,80,72,63,98},这样一个数组的排序就变成了两个小数组的排序--53左边的数组和53右边的数组,而这两个数组继续用同样的方式继续下去,一直到顺序完全正确。
  一般来说,冒泡法是程序员最先接触的排序方法,它的优点是原理简单,编程实现容易,但它的缺点就是--程序的大忌--速度太慢。
附上快速排序代码:
#include

void quicksort(int a[],int left,int right){ int i,j,temp; i=left; j=right; temp=a[left]; if(left>right) return; while(i!=j) { while(a[j]>=temp&&j>i) j--; if(j>i) a[i++]=a[j]; while(a[i]<=temp&&j>i) i++; if(j>i) a[j--]=a[i]; } a[i]=temp; quicksort(a,left,i-1); quicksort(a,i+1,right);}void main(){ int a[]={53,12,98,63,18,72,80,46,32,21}; int i; quicksort(a,0,9); /*排好序的结果*/ for(i=0;i<10;i++) printf("%4d\n",a[i]);}

如何用java实现快速排序,简答讲解下原理

快速排序思想:
通过对数据元素集合Rn 进行一趟排序划分出独立的两个部分。其中一个部分的关键字比另一部分的关键字小。然后再分别对两个部分的关键字进行一趟排序,直到独立的元素只有一个,此时整个元素集合有序。
快速排序的过程,对一个元素集合R[ low ... high ] ,首先取一个数(一般是R[low] )做参照 , 以R[low]为基准重新排列所有的元素。
所有比R[low]小的放前面,所有比R[low] 大的放后面,然后以R[low]为分界,对R[low ... high] 划分为两个子集和,再做划分。直到low >= high 。
比如:对R={37, 40, 38, 42, 461, 5, 7, 9, 12}进行一趟快速排序的过程如下(注:下面描述的内容中元素下表从 0 开始):
开始选取基准 base = 37,初始位置下表 low = 0 , high = 8 , 从high=8,开始如果R[8] < base , 将high位置中的内容写入到R[low]中, 将high位置空出来, low = low +1 ;
从low开始探测,由于low=1 , R[low] > base ,所以将R[low]写入到R[high] , high = high -1 ;
检测到low < high ,所以第一趟快速排序仍需继续:
此时low=1,high=7,因为 R[high] < base ,所以将 R[high] 写入到到R[low]中,low = low + 1;
从low开始探测,low = 2 , R[low] >base ,所以讲R[low]写入到R[high],high=high-1;
继续检测到 low 小于high
此时low=2,high=6,同理R[high] < base ,将R[high] 写入到R[low]中,low=low+1;
从low继续探测,low = 3 , high=6 , R[low] > base , 将R[low]写入到R[high]中,high = high-1;
继续探测到low小于high
此时low=3,high=5,同理R[high] < base,将R[high]写入到R[low]中,low = low +1;
从low继续探测,low = 4,high=5,由于R[low] > base , 将R[low]写入到R[high]中,high = high -1 ;
此时探测到low == high == 4 ;该位置即是base所在的位置,将base写入到该位置中.
然后再对子序列Rs1 = {12,9,7,5} 和 Rs2={461,42,38,40}做一趟快速排序,直到Rsi中只有一个元素,或没有元素。
快速排序的Java实现:
private static boolean isEmpty(int[] n) {
return n == null || n.length == 0;
}

阅读更多 >>>  shellsort排序,shell 排序

// ///////////////////////////////////////////////////
/**
* 快速排序算法思想——挖坑填数方法:
*
* @param n 待排序的数组
*/
public static void quickSort(int[] n) {
if (isEmpty(n))
return;
quickSort(n, 0, n.length - 1);
}

public static void quickSort(int[] n, int l, int h) {
if (isEmpty(n))
return;
if (l < h) {
int pivot = partion(n, l, h);
quickSort(n, l, pivot - 1);
quickSort(n, pivot + 1, h);
}
}

private static int partion(int[] n, int start, int end) {
int tmp = n[start];
while (start < end) {
while (n[end] >= tmp && start < end)
end--;
if (start < end) {
n[start++] = n[end];
}
while (n[start] < tmp && start < end)
start++;
if (start < end) {
n[end--] = n[start];
}
}
n[start] = tmp;
return start;
}
在代码中有这样一个函数:
public static void quickSortSwap(int[] n, int l, int h)
该函数可以实现,元素集合中特定的 l 到 h 位置间的数据元素进行排序。

快速排序在什么情况下最能发挥其长处

最好情况:
每一次划分对一个记录定位后,该记录的左侧子表与右侧子表的长度相同,为O(nlog2n)。
最坏情况:
每次划分只得到一个比上一次划分少一个记录的子序列(另一个子序列为空),为 O(n2)。
被排序的数据中含有多个相同的排序关键字
最好情况:
每一次划分对一个记录定位后,该记录的左侧子表与右侧子表的长度相同,为O(nlog2n)。
最坏情况:
每次划分只得到一个比上一次划分少一个记录的子序列(另一个子序列为空),为 O(n2)。
扩展资料
快速排序实现原理:
快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
1、默认数组的第一个数为基准数据,赋值给key,即key=array[low]。
2、因为默认数组的第一个数为基准,所以从后面开始向前搜索(high–),找到第一个小于key的array[high],就将 array[high] 赋给 array[low],即 array[low] = array[high]。(循环条件是 array[high] >= key;结束时 array[high] < key)
3、此时从前面开始向后搜索(low++),找到第一个大于key的array[low],就将 array[low] 赋给 array[high],即 array[high] = array[low]。(循环条件是 array[low] <= key;结束时 array[low] > key)
4、循环 2-3 步骤,直到 low=high,该位置就是基准位置。
5、把基准数据赋给当前位置。

如何理解java数据结构中的快速排序方法

原理:
快速排序也是分治法思想的一种实现,他的思路是使数组中的每个元素与基准值(Pivot,通常是数组的首个值,A[0])比较,数组中比基准值小的放在基准值的左边,形成左部;大的放在右边,形成右部;接下来将左部和右部分别递归地执行上面的过程:选基准值,小的放在左边,大的放在右边。。。直到排序结束。
步骤:
1.找基准值,设Pivot = a[0]
2.分区(Partition):比基准值小的放左边,大的放右边,基准值(Pivot)放左部与右部的之间。
3.进行左部(a[0] - a[pivot-1])的递归,以及右部(a[pivot+1] - a[n-1])的递归,重复上述步骤。
排序效果:

快速排序特点

排序流程
快速排序算法通过多次比较和交换来实现排序,其排序流程如下:[2]
(1)首先设定一个分界值,通过该分界值将数组分成左右两部分。[2]
(2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。[2]
(3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。[2]
(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。[2]
排序步骤
原理
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选
快排图
用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它左边,所有比它大的数都放到它右边,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。[1]
一趟快速排序的算法是:[1]
1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;[1]
2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];[1]
3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]的值交换;[1]
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]的值交换;[1]
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-完成的时候,此时令循环结束)。
快速排序(Quicksort)是对冒泡排序的一种改进,由东尼·霍尔在1960年提出。 快速排序是指通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序。整个排序过程可以递归进行,以此达到整个数据变成有序序列。
分类
排序算法
数据结构
不定
最坏空间复杂度
根据实现的方式不同而不同
快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。
步骤为:
从数列中挑出一个元素,称为“基准”(pivot),
重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任何一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归到最底部时,数列的大小是零或一,也就是已经排序好了。这个算法一定会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
在简单的伪代码中,此算法可以被表示为:
function quicksort(q)
{
var list less, pivotList, greater
if length(q) ≤ 1
return q
else
{
select a pivot value pivot from q
for each x in q except the pivot element
{
if x
<pivot then add x to less
if x ≥ pivot then add x to greater

}

add pivot to pivotList

return concatenate(quicksort(less), pivotList, quicksort(greater))

}

}

原地(in-place)分区的版本

上面简单版本的缺点是,它需要的额外存储空间,也就跟归并排序一样不好。额外需要的存储器空间配置,在实际上的实现,也会极度影响速度和缓存的性能。有一个比较复杂使用原地(in-place)分区算法的版本,且在好的基准选择上,平均可以达到空间的使用复杂度。

function partition(a, left, right, pivotIndex)

{

pivotValue = a[pivotIndex]

swap(a[pivotIndex], a[right]) // 把pivot移到结尾

storeIndex = left

for i from left to right-1

{

if a[i]<= pivotValue

{

swap(a[storeIndex], a[i])

storeIndex = storeIndex + 1

}

}

swap(a[right], a[storeIndex]) // 把pivot移到它最後的地方

return storeIndex

}

这是原地分区算法,它分区了标示为"左边(left)"和"右边(right)"的序列部分,借由移动小于的所有元素到子序列的开头,留下所有大于或等于的元素接在他们后面。在这个过程它也为基准元素找寻最后摆放的位置,也就是它回传的值。它暂时地把基准元素移到子序列的结尾,而不会被前述方式影响到。由于算法只使用交换,因此最后的数列与原先的数列拥有一样的元素。要注意的是,一个元素在到达它的最后位置前,可能会被交换很多次。

一旦我们有了这个分区算法,要写快速排列本身就很容易:

procedure quicksort(a, left, right)

if right>left

select a pivot value a[pivotIndex]

pivotNewIndex := partition(a, left, right, pivotIndex)

quicksort(a, left, pivotNewIndex-1)

quicksort(a, pivotNewIndex+1, right)

这个版本经常会被使用在命令式语言中,像是C语言。

快速排序

快速排序是二叉查找树(二叉搜索树)的一个空间最优化版本。不是循序地把数据项插入到一个明确的树中,而是由快速排序组织这些数据项到一个由递归调用所隐含的树中。这两个算法完全地产生相同的比较次数,但是顺序不同。对于排序算法的稳定性指标,原地分区版本的快速排序算法是不稳定的。其他变种是可以通过牺牲性能和空间来维护稳定性的。

阅读更多 >>>  sorting是什么意思,soting的翻译是:什么意思

网站数据信息

"快速排序原理,快速排序在什么情况下最能发挥其长处"浏览人数已经达到18次,如你需要查询该站的相关权重信息,可以点击进入"Chinaz数据" 查询。更多网站价值评估因素如:快速排序原理,快速排序在什么情况下最能发挥其长处的访问速度、搜索引擎收录以及索引量、用户体验等。 要评估一个站的价值,最主要还是需要根据您自身的需求,如网站IP、PV、跳出率等!