1、概述:
- 设要排序的数组是A[0]……A[N-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的值,
5.使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。
2、图解:
3、代码:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace 快速排序
8 {
9 class Program
10 {
11
12 /// <summary>
13 /// 对数组dataArray中索引从left到right之间的数做排序
14 /// </summary>
15 /// <param name="dataArray">要排序的数组</param>
16 /// <param name="left">要排序数据的开始索引</param>
17 /// <param name="right">要排序数据的结束索引</param>
18 static void QuickSort(int[] dataArray, int left, int right)
19 {
20 if (left < right)
21 {
22
23 int x = dataArray[left];//基准数, 把比它小或者等于它的 放在它的左边,然后把比它大的放在它的右边
24 int i = left;
25 int j = right;//用来做循环的标志位
26
27 while (true && i < j)//当i==j的时候,说明我们找到了一个中间位置,这个中间位置就是基准数应该所在的位置
28 {
29
30 //从后往前比较(从右向左比较) 找一个比x小(或者=)的数字,放在我们的坑里 坑位于i的位置
31 while (true && i < j)
32 {
33 if (dataArray[j] <= x) //找到了一个比基准数 小于或者等于的数子,应该把它放在x的左边
34 {
35 dataArray[i] = dataArray[j];
36 break;
37 }
38 else
39 {
40 j--;//向左移动 到下一个数字,然后做比较
41 }
42 }
43
44 //从前往后(从左向右)找一个比x大的数字,放在我们的坑里面 现在的坑位于j的位置
45 while (true && i < j)
46 {
47 if (dataArray[i] > x)
48 {
49 dataArray[j] = dataArray[i];
50 break;
51 }
52 else
53 {
54 i++;
55 }
56 }
57 }
59 //跳出循环 现在i==j i是中间位置
60 dataArray[i] = x;// left -i- right
62 QuickSort(dataArray, left, i - 1);
63 QuickSort(dataArray, i + 1, right);
64 }
65 }
67 static void Main(string[] args)
68 {
69 int[] data = new int[] { 42, 20, 17, 27, 13, 8, 17, 48 };
70
71 QuickSort(data, 0, data.Length - 1);
72
73 foreach (var temp in data)
74 {
75 Console.Write(temp + " ");
76 }
77 Console.ReadKey();
78 }
79 }
80 }