时间复杂度:O(n*logn) 以2为底的对数
空间复杂度:O(logn) 以2为底的对数
稳定性:不稳定
举例:【3,1,5,6,7】 红色背景为基准
第一轮:
【3 (l),1,5,6,7(r)】
【3 (l),1,5,6(r),7】
【3 (l),1,5(r),6,7】
【3 (l),1(r),5,6,7】
【1 (l),3(r),5,6,7】 此时l处符合序列 l++
【1 ,3(r)(l),5,6,7】
接下来是从左向右找比基准大的 并交换 本例特殊 没有
此时r==l 分割数组 对两部分再进行排序
/// <summary>
/// 快速排序
/// </summary>
/// <param name="nums">待排数据</param>
/// <param name="left">范围-数据左边界下标</param>
/// <param name="right">范围-数据有边界下标</param>
public void Sort(int[] nums, int left, int right)
{
//每轮以左边界元素为基准 调整数组 使得基准右侧元素都大于基准 基准左侧元素都小于基准
//调整的流程为 令设两个游标 l=left r=right (假设第一次判断就找到了符合交换条件的)
//首先从右侧向左侧寻找小于基准的 并和l处元素交换(基准-l,x,x,x,y-r)->(y-l,x,x,x,基准-r) 此时l处元素符合序列,所以l++ (y,x-l,x,x,基准-r)
//此时基准在r处 从左侧向右侧寻找大于基准的 并和r处元素交换 (y,x-l,x,x,基准-r)->(y,基准-l,x,x,x-r) 此时r处元素符合序列 所以r-- (y,基准-l,x,x-r,x)
//循环上面两步 直到l=r 此时以l(或r)为分割点,对两边数组递归快速排序 当数组中只有一个元素退出
int l = left, r = right;
//找分割点
while (l < r)
{
//从右向左找小的
while (nums[r] >= nums[l] && l < r)
{
r--;
}
if (l < r) //说明找到小的了 而不是因为l>r而找到的
{
int tmp = nums[l];
nums[l] = nums[r];
nums[r] = tmp;
l++;
}
//从左向右找大的
while (nums[l] <= nums[r] && l < r)
{
l++;
}
if (l < r)
{
int tmp = nums[l];
nums[l] = nums[r];
nums[r] = tmp;
r--;
}
}
//while循环结束 此时l==r 为分割点
//判断两边的数组长度 如果大于1 继续递归
if (right - l > 1)
{
Sort(nums, l + 1, right);
}
if (l - left > 1)
{
Sort(nums, left, l - 1);
}
}