算法 quick sort

  1. // --------------------------------------------------------------------------------------------------------------------
  2. //
  3. //
  4. // Respect the work.
  5. //
  6. // </copyright>
  7. // <summary>
  8. //
  9. // The quick sort.
  10. //
  11. // 高速排序(QuickSort)是对冒泡排序的一种改进。它的基本思想是:通过一趟排序将要排序的数据切割成独立的两部分,当中一部分的全部数据都比另外一部分的全部数据要小,然后再按此方法对这两部分数据分别进行高速排序。整个排序过程能够递归进行,以此达到整个数据变成有序序列。
  12. //
  13. // 设要排序的数组是a[0]...a[N-1],首先随意选取一个数据(通常选用数组的首元素)作为重要数据,然后将全部比它小的数都放到它的前面,全部比它大的数都放到它的后面,这个过程称为一趟高速排序。

    值得注意的是,高速排序不是一种稳定的排序算法。也就是说,多个同样的值的相对位置或许会在算法结束时产生变动。

  14. // 一趟高速排序的算法是:
  15. // 1)设置两个变量i、j,排序開始的时候:i=0,j=N-1。
  16. // 2)以数组首元素作为重要数据,赋值给pivot,即pivot=a[0]。
  17. // 3)从j開始向前搜索,即由后開始向前搜索(j--),找到第一个小于pivot的值a[j],将a[j]赋值给a[i];
  18. // 4)从i開始向后搜索,即由前開始向后搜索(i++),找到第一个大于pivot的值a[i],将a[i]赋值给a[j];
  19. // 5)反复第3、4步,直到i==j;(在3、4步中。若没找到符合条件的值,即3中a[j]不小于pivot,4中a[i]不大于pivot的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。

    若找到符合条件的值,进行替换的时候i、j指针位置不变。

  20. //
  21. // 高速排序的平均时间复杂度是:O(nlog<sub>2</sub>n)。
  22. //
  23. // </summary>
  24. // --------------------------------------------------------------------------------------------------------------------
  25. namespace CSharpLearning
  26. {
  27. using System;
  28. /// <summary>
  29. /// The program.
  30. /// </summary>
  31. public static class Program
  32. {
  33. /// <summary>
  34. /// The main.
  35. /// </summary>
  36. public static void Main()
  37. {
  38. int[] a = { 101, 93, 856, 7, 62, 15, 84, 3, 298, 1256 };
  39. Console.WriteLine("Before Quick Sort:");
  40. foreach (int i in a)
  41. {
  42. Console.Write(i + " ");
  43. }
  44. Console.WriteLine("\r\n");
  45. Console.WriteLine("In Quick Sort:");
  46. QuickSort(a, 0, 9);
  47. Console.WriteLine("\r\nAfter Quick Sort:");
  48. foreach (int i in a)
  49. {
  50. Console.Write(i + " ");
  51. }
  52. Console.WriteLine(string.Empty);
  53. }
  54. /// <summary>
  55. /// 高速排序。
  56. /// </summary>
  57. /// <param name="a">
  58. /// 待排序数组。
  59. /// </param>
  60. /// <param name="low">
  61. /// 待排序数组的排序起始位置。
  62. /// </param>
  63. /// <param name="high">
  64. /// 待排序数组的排序终止位置。
  65. /// </param>
  66. private static void QuickSort(int[] a, int low, int high)
  67. {
  68. if (low >= high)
  69. {
  70. return;
  71. }
  72. int pivot = QuickSortOnce(a, low, high);
  73. // 输出每一次排序。
  74. foreach (int i in a)
  75. {
  76. Console.Write(i + " ");
  77. }
  78. Console.WriteLine(string.Empty);
  79. // 对枢轴的左端进行排序。
  80. QuickSort(a, low, pivot - 1);
  81. // 对枢轴的右端进行排序。
  82. QuickSort(a, pivot + 1, high);
  83. }
  84. /// <summary>
  85. /// 一趟高速排序。

  86. /// </summary>
  87. /// <param name="a">
  88. /// 待排序数组。

  89. /// </param>
  90. /// <param name="low">
  91. /// 待排序数组的排序起始位置。
  92. /// </param>
  93. /// <param name="high">
  94. /// 待排序数组的排序终止位置。
  95. /// </param>
  96. /// <returns>
  97. /// 返回枢轴的位置。
  98. /// </returns>
  99. private static int QuickSortOnce(int[] a, int low, int high)
  100. {
  101. // 将首元素作为枢轴。
  102. int pivot = a[low];
  103. int i = low, j = high;
  104. while (i < j)
  105. {
  106. // 从右到左,寻找首个小于pivot的元素。

  107. while (a[j] >= pivot && i < j)
  108. {
  109. j--;
  110. }
  111. // 运行到此,j一定指向从右端起首个小于或等于pivot的元素。运行替换。
  112. a[i] = a[j];
  113. // 从左到右,寻找首个大于pivot的元素。

  114. while (a[i] <= pivot && i < j)
  115. {
  116. i++;
  117. }
  118. // 运行到此。i一定指向从左端起首个大于或等于pivot的元素。

    运行替换。

  119. a[j] = a[i];
  120. }
  121. // 退出while循环,运行至此,必然是i==j的情况。i(或j)指向的即是枢轴的位置,定位该趟排序的枢轴并将该位置返回。
  122. a[i] = pivot;
  123. return i;
  124. }
  125. }
  126. }
  127. // Output:
  128. /*
  129. Before Quick Sort:
  130. 101 93 856 7 62 15 84 3 298 1256
  131. In Quick Sort:
  132. 3 93 84 7 62 15 101 856 298 1256
  133. 3 93 84 7 62 15 101 856 298 1256
  134. 3 15 84 7 62 93 101 856 298 1256
  135. 3 7 15 84 62 93 101 856 298 1256
  136. 3 7 15 62 84 93 101 856 298 1256
  137. 3 7 15 62 84 93 101 298 856 1256
  138. After Quick Sort:
  139. 3 7 15 62 84 93 101 298 856 1256
  140. */
时间: 2024-11-06 12:14:21

算法 quick sort的相关文章

笔试算法题(54):快速排序实现之单向扫描、双向扫描(single-direction scanning, bidirectional scanning of Quick Sort)

议题:快速排序实现之一(单向遍历) 分析: 算法原理:主要由两部分组成,一部分是递归部分QuickSort,它将调用partition进行划分,并取得划分元素P,然后分别对P之前的部分和P 之后的部分递归调用QuickSort:另一部分是partition,选取划分元素P(随机选取数组中的一个元素,交换到数组末尾位置),定义两个标记 值left和right,随着划分的进行,这两个标记值将数组分成三部分,left之左的部分是小于划分元素P的值,left和right之间的部分是大 于等于划分元素P的

笔试算法题(55):快速排序实现之非递归实现,最小k值选择(non-recursive version, Minimal Kth Selection of Quick Sort)

议题:快速排序实现之五(非递归实现,短序列优先处理,减少递归栈大小) 分析: 算法原理:此算法实现适用于系统栈空间不足够快速排序递归调用的需求,从而使用非递归实现快速排序算法:使用显示下推栈存储快速排序中的每一次划分结果 (将left和right都压入堆栈),并且首先处理划分序列较短的子序列(也就是在得到一次划分的左右部分时,首先将长序列入栈,然后让段序列入栈), 这样可以保证当快速排序退化的线性效率的时候,栈大小仍旧在㏒N范围内.算法策略类似于最小子树优先遍历规则: 弱势:当序列已经就绪,每次

Collection of algorithm for sorting. 常见排序算法集(三) —— Quick Sort

Quick Sort 快排,一个排序方法能直接享受这样的名称殊荣,呵呵,可见其威力与重要性. 其中最重要的思想就是 "分治"-- divide and conquer ! 这里排序用到的思想极其简单,却是很实用的!小孩子都会的简单想法. 先把所有数据分成三个部分. 在所有数据中选取某一元素X,比X小的放左边,比X大的放右边. 接着把这一思想同样分别施加在X元素的左边和右边部分,同样继续划分,选出一个元素X' 比X'小的放左边比X'大的放右边. 继续施加这种划分策略,直到划分的元素很少(

经典排序算法 - 快速排序Quick sort

经典排序算法 - 快速排序Quick sort 原理,通过一趟扫描将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列 举个例子 如无序数组[6 2 4 1 5 9] a),先把第一项[6]取出来, 用[6]依次与其余项进行比较, 如果比[6]小就放[6]前边,2 4 1 5都比[6]小,所以全部放到[6]前边 如果比[6]大就放[6]后边,9比[6]大,放到[6

排序算法之快速排序(Quick Sort) -- 适用于Leetcode 75 Sort Colors

Quick Sort使用了Divide and Concur的思想: 找一个基准数, 把小于基准数的数都放到基准数之前, 把大于基准数的数都放到基准数之后 Worst case: O(n^2) Average case: O(nlogN) 步骤: 初始的数组 Array a[]: 0 1 2 3 4 5 6 7 8 9 51 73 52 18 91 7 87 73 48 3 基准数: X = a[0] = 51 i 的值: i = 0 j 的值: j = 9 (a.length) Step 1:

C++: quick sort(快排序)

到目前为止, 我们已经学习到了插入排序, 冒泡排序, 选择排序(selection). 这些排序算法都是comparision based sorting algorithms(即涉及到元素大小的比较来决定元素的先后顺序). 而且算法的时间复杂度上均为O(n^2).但是comparision based 的排序算法远非这几个算法. 而且可以通过利用其它的一些手段(例如divide and conquer technique, 分治法)实现对基于比较的排序算法的时间复杂度降低到O(nlogn).

快速排序(Quick Sort)

快速排序是初学者比较难理解的几个算法之一,这里尽可简单化地讲解,希望能帮到大家. 快速排序基本步骤: 从数列中挑出一个元素,称为"基准"(pivot). 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边).在这个分区结束之后,该基准就处于数列的中间位置.这个称为分区(partition)操作. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序. 下面这幅图会帮助你理解.选中的pivot用蓝色表示:

快速排序(Quick Sort)的C语言实现

快速排序(Quick Sort)的基本思想是通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对着两部分记录继续进行排序,以达到整个序列有序,具体步骤为 设立枢轴,将比枢轴小的记录移到低端,比枢轴大的记录移到高端,直到low=high停止 分别对枢轴低高端部分再次快速排序(即重复第1步) 重复第1.2步,直到low=high停止 C语言实现(编译器Dev-c++5.4.0,源代码后缀.cpp) 原创文章,转载请注明来自钢铁侠Mac博客http:/

Quick Sort

(referrence: GeeksforGeeks) Like Merge Sort, Quick Sort is also a divide & conquer problem. It picks an element as pivot and partitions the given array around the picked pivot. Different versions of Picking pivot 1. Always pick first element as pivot