基本思想
- 从数列中取出一个数作为基准数
- 分区:将比这个数大的全放到右边,小于或等于它的放到左边
- 对左右区间重复第二步,直到各区间只有一个数
详细步骤
- 取第一个数为基准数
- 使用双指针i=0、j=9,创建临时变量temp,将arr[0]放入temp中。因为arr[0]已经保存,所以相当于这个索引空缺。
初始数组,红色表示空缺
-
从j开始向前找一个第一个小于或等于temp的数,当j=9时符合,将arr[9]放入空缺中(arr[0]=arr[9]),i++,arr[9]成为新的空缺。
-
再从i开始向后找第一个大于temp的数,当i=1时符合,将arr[1]放入空缺中(arr[9]=arr[1]),j- -,arr[1]成为新空缺。
-
此时i=1,j=8,temp=25;重复3.4步,先从后向前找,再从前向后找。
从j开始向前:当j=8,符合条件,将arr[8]填到空缺处arr[1](arr[1]=arr[8]),i++。
从i开始向后:当i=5,符合条件,将arr[5]填到空缺处arr[8](arr[8]=arr[5]),j- -。
6.直到i=j=6时,arr[6]为空缺
可以看出arr[6]前面的数字都小于temp,arr[6]后面的数字都大于temp。
7.再对arr[0—5]和arr[7—9]两个子区间重复上述步骤完成排序(递归)。
代码
class Program
{
/// <summary>
/// 对数组arr中从索引left到right之间的数做快速排序
/// </summary>
/// <param name="arr">要排序的数组</param>
/// <param name="left">要排序数据的开始索引</param>
/// <param name="right">要排序数据的结束索引</param>
static void QuickSort(int[] arr, int left, int right)
{
if (left < right)
{
int temp = arr[left];//基准数,把 <= temp 的放在temp的左边,把 >= temp 的放在temp的右边
int i = left;
int j = right;//用来循环的标志位
while (i < j)//当i==j时,找到了中间位置,就是基准数应该在的位置
{
//从右到左比较,找一个比temp小或相等的数字,放在空缺里(此时空缺在i)
while (i < j)
{
if (arr[j] <= temp)//找到了一个比基准数小或相等的数字,把它放在x左边
{
arr[i] = arr[j];
break;
}
else
j--;//向左移动到下一个数字再做比较
}
//从左到右比较,找一个比temp大的数字,放在空缺里(此时空缺在j)
while (i < j)
{
if (arr[i] > temp)//找到了一个比基准数大的数字,把它放在temp右边
{
arr[j] = arr[i];
break;
}
else
i++;
}
}
//跳出循环,此时i==j,i是中间位置
arr[i] = temp;//分为left——i,i——right两个区间
QuickSort(arr, left, i - 1);
QuickSort(arr, i + 1, right);
}
}
static void Main(string[] args)
{
int[] arr = new int[] { 25, 34, 16, 8, 19, 36, 22, 46, 5, 2 };
QuickSort(arr, 0, arr.Length - 1);
foreach (var item in arr)
Console.Write(item + " ");
}
}