当前位置:   article > 正文

排序算法-----快速排序(递归)_递归法实现快速排序算法

递归法实现快速排序算法

目录

前言

快速排序

 步骤原理

大致思路

流程

动态图

代码实现

算法分析

空间复杂度

时间复杂度

稳定性


前言

        今天我们开始学习排序算法中的快速排序算法,既然叫快速排序,那肯定是体现在快这方面,相较于前面所学习过的排序算法,快速排序是比这些算法的速度要快的,将来很多时候我们都会用到快速排序来去做排序的,下面就一起来学习吧!

快速排序

        快速排序(Quicksort),计算机科学词汇,适用领域Pascal,C++等语言,是对冒泡排序算法的一种改进。

        快速排序采用的是分治思想,即在一个无序的序列中选取一个任意的基准元素pivot,利用pivot将待排序的序列分成两部分,前面部分元素均小于或等于基准元素,后面部分均大于或等于基准元素,然后采用递归的方法分别对前后两部分重复上述操作,直到将无序序列排列成有序序列。

 步骤原理

大致思路

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

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

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

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

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

流程

现在给定一个数组初始 [25,24,6,65,11,43,22,51] ,然后进行快速排序

 第一步,先选取一个参考数字temp,一般选取第一个即temp=25,然后标记最左边和最右边数字的位置分别为i, j

 25        24        6        64        11        43        22        51

  i                                                                                 j

temp

 第二步,先去向左移动j 的位置,当j指向的数字小于temp时候,就停止移动,然后开始向右移动i 

当i 移动到比temp要大的数字时,停止移动,此时将i 和 j 指向的数字进行交换,如下所示:

 25        24        6        64        11        43        22        51

temp                             i                                   j

交换后:

 25        24        6        22        11        43        65       51

temp                             i                                   j

 第三步,此时,开始接着移动 j,当j 移动到比temp要小的数字的时候,停止移动, 如下所示:

 25        24        6        22        11        43        65       51

temp                             i           j

 然后开始移动i ,当i 移动到与j 相遇的位置时,i停止移动(如果i 移动到比temp要大的数字的时候就执行上面的第二步,i与j 进行数字交换)

 25        24        6        22        11        43        65       51

temp                                        i,j

第四步,此时,i与j指向的数字与temp指向的数字进行数字交换

 11        24        6        22        25        43        65       51

temp                                        i,j

这时候我们会发现,此时i和j指向的数字的位置,左边的都比这个数字要小,右边的都比这个数字要大,于是我们就可以去进入到递归,分别对左边和右边的数字进行以上步骤的递归,最后两边的数字都会被排好序。

动态图

 

代码实现

  1. #include<stdio.h>
  2. //快速排序---递归实现
  3. void quick_sort(int* n, int left,int right) {
  4. int i, j, temp;
  5. i = left;
  6. j = right;
  7. if (i > j) {
  8. return;
  9. }
  10. else {
  11. temp = n[left];
  12. while (i != j) {
  13. while (n[j] >= temp && i < j)//先向左移动j
  14. j--;
  15. while (n[i] <= temp && i < j) //再向右移动i
  16. i++;
  17. if (i < j) {//此时对i和j指向的数字进行数字交换
  18. int num = n[i];
  19. n[i] = n[j];
  20. n[j] = num;
  21. }
  22. }//当i和j相遇的时候就结束循环
  23. //此时i与j相遇,就与temp交换
  24. int new_temp = n[i];
  25. n[i] = n[left];
  26. n[left] = new_temp;
  27. }
  28. //最后左右边依次进入到递归
  29. quick_sort(n, left, i - 1); //左边的数字都比temp要小
  30. quick_sort(n, i + 1, right); //右边的数字都比temp要大
  31. }
  32. int main() {
  33. int array[8] = { 25,24,6,65,11,43,22,51 };
  34. printf("排序前:");
  35. for (int i = 0; i < sizeof(array) / sizeof(int); i++) {
  36. printf("%d ", array[i]);
  37. }
  38. printf("\n排序后:");
  39. quick_sort(array, 0, sizeof(array) / sizeof(int)-1);
  40. for (int i = 0; i < sizeof(array) / sizeof(int); i++) {
  41. printf("%d ", array[i]);
  42. }
  43. }
  44. //排序前:25 24 6 65 11 43 22 51
  45. //排序后:6 11 22 24 25 43 51 65

算法分析

空间复杂度

快速排序算法没有涉及到空间的开辟,使用的空间是原数组空间,空间复杂度为O(1)

时间复杂度

快速排序之所以比较快,是因为与冒泡排序相比,每次的交换时跳跃式的,每次排序的时候设置一个基准点,将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全部放到基准点的右边。这样整体交换次数和比较次数就少很多, 故排序速度就提高了许多,当然如果是最坏的情况下时间复杂度还是为O(n^2),其平均的时间复杂度为 O(nlog2​n)

稳定性

 俗话说得好:有得必有失。快速排序虽然排序速度快了很多,但是其缺牺牲了稳定性,当出现相同大小元素的时候,相同大小元素的相对位置会发生改变,每次递归都会发生变化,这就导致了快速排序的稳定性不好,这是因为快速排序改变了交换的规则,使用跳跃式交换,没有进行数字大小的一一比较,故快速排序是不稳定的,所以选择排序算法的时候要慎重选择,充分考虑到稳定性

好了,以上就是今天的全部内容了,我们下一期再见! 

分享一张壁纸: 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/456168
推荐阅读
相关标签
  

闽ICP备14008679号