当前位置:   article > 正文

排序算法进阶(一)——快速排序算法_快速排序串行算法

快速排序串行算法

偶然间看了一篇微信上的文章,里面介绍了十大算法,分别是:

一:快速排序算法

二:堆排序算法

三:归并排序

四:二分查找算法

五:BFPRT(线性查找算法)

六:DFS(深度优先搜索)

七:BFS(广度优先搜索)

八:Dijkstra算法

九:动态规划算法

十:朴素贝叶斯分类算法

虽然前面自己整理里几个基本排序查找算法,但看了这篇文章真有点惭愧啊!因此想抽空学习整理一下这些算法。

首先就从快速排序算法入手,废话不多说,上图:

lxzh

不过,正式写之前还是有必要做一些简单介绍,掌握一个好的算法,它的背景尝试也得了解一下嘛!

1、算法的概念:

快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。
2、算法思想:
用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串(sub-lists):通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

3、实现思路:

①以第一个关键字 n1 为控制字,将 [n1 ,n2 ,…,nk ] 分成两个子区,使左区所有关键字小于等于 n1 ,右区所有关键字大于等于 n1 ,最后控制字居两个子区中间的适当位置。在子区内数据尚处于无序状态。  ②把左区作为一个整体,用①的步骤进行处理,右区进行相同的处理。(即递归) ③重复第①、②步,直到左区处理完毕。

4、算法步骤:

1)从数列中挑出一个元素,称为 “基准”(pivot),

2)重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。

3)递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

5、实现代码:

  1. public static void QuickSort(int n[], int left, int right) {
  2. int mid;
  3. if (left < right) {
  4. mid = Partion(n, left, right);
  5. QuickSort(n, left, mid - 1);
  6. QuickSort(n, mid + 1, right);
  7. }
  8. }
  9. public static int Partion(int n[], int left, int right) {
  10. int pivot = n[left];// 也可以从n[right]开始
  11. while (left < right) {
  12. while (left < right && n[right] >= pivot)
  13. right--;
  14. if (left < right) {
  15. n[left++] = n[right];
  16. }
  17. while (left < right && n[left] <= pivot)
  18. left++;
  19. if (left < right) {
  20. n[right--] = n[left];
  21. }
  22. }
  23. n[left] = pivot;
  24. return left;
  25. }
为了更加直观的显示算法运行过程中数组数据变化情况,这里可以加一个打印函数:

  1. public static void printList(int[] n) {
  2. int len = n.length;
  3. for (int i = 0; i < len; i++) {
  4. System.out.print(n[i] + ",");
  5. }
  6. System.out.println("");
  7. }
随便写一个数组int n[] = { 7, 8, 1, 9, 5, 10, 3, 2, 11 };

通过打印中间结果来展示排序情况,完整代码如下:

  1. package com.lxzh123.quicksort;
  2. /**
  3. * @author: lxzh
  4. * @E-mail: 1239848066@qq.com
  5. * @qq: 1239848066
  6. * @Date: 2015年8月1日上午12:01:31
  7. * @version: 1.0 Dscription: 快速排序
  8. */
  9. public class QuickSortDemo {
  10. public static void main(String[] args) {
  11. int n[] = { 7, 8, 1, 9, 5, 10, 3, 2, 11 };
  12. printList(n);
  13. QuickSort(n, 0, n.length - 1);
  14. printList(n);
  15. }
  16. public static void QuickSort(int n[], int left, int right) {
  17. int mid;
  18. if (left < right) {
  19. mid = Partion(n, left, right);
  20. QuickSort(n, left, mid - 1);
  21. QuickSort(n, mid + 1, right);
  22. }
  23. }
  24. public static int Partion(int n[], int left, int right) {
  25. int pivot = n[left];// 也可以从n[right]开始
  26. while (left < right) {
  27. while (left < right && n[right] >= pivot)
  28. right--;
  29. if (left < right) {
  30. n[left++] = n[right];
  31. printList(n);
  32. }
  33. while (left < right && n[left] <= pivot)
  34. left++;
  35. if (left < right) {
  36. n[right--] = n[left];
  37. printList(n);
  38. }
  39. System.out.println();
  40. }
  41. n[left] = pivot;
  42. printList(n);
  43. return left;
  44. }
  45. public static void printList(int[] n) {
  46. int len = n.length;
  47. for (int i = 0; i < len; i++) {
  48. System.out.print(n[i] + ",");
  49. }
  50. System.out.println("");
  51. }
  52. }
编译运行后输出结果:

7,8,1,9,5,10,3,2,11,
2,8,1,9,5,10,3,2,11,
2,8,1,9,5,10,3,8,11,

2,3,1,9,5,10,3,8,11,
2,3,1,9,5,10,9,8,11,

2,3,1,5,5,10,9,8,11,

2,3,1,5,7,10,9,8,11,
1,3,1,5,7,10,9,8,11,
1,3,3,5,7,10,9,8,11,

1,2,3,5,7,10,9,8,11,

1,2,3,5,7,10,9,8,11,
1,2,3,5,7,8,9,8,11,

1,2,3,5,7,8,9,10,11,

1,2,3,5,7,8,9,10,11,
1,2,3,5,7,8,9,10,11,


仔细分析一下输出结果就能很好的理解该算法的原理啦!不多说了,读者自己去品味吧~

如果闲来没事的话,读者可以利用这个排序原理自己制作文中的那个动图,有兴趣的可以尝试一下!

注:动态图片展示的是以数组最后一个值为基准,稍微修改一下上述代码就可以达到动图中的效果。

原创博客 反馈请猛戳:

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

闽ICP备14008679号