快速排序的时间复杂度为O(nlogn)。

关于快速排序的几点注意事项:

  1. 每次排序先选取一个元素,记为flag。目的是排序后保证flag左边的数不大于flag,右边的数不小于flag。一般以第一个元素为准。该位置元素默认“取出”。
  2. 最左边的元素下标记为low,指向最左边元素。最右边的元素下表记为high。
  3. 先看high元素是否大于flag,若大于等于则继续左移high。若小于则将high对应元素放到low上(此时low对应flag,已取出)并右移low(这里判定条件为如果low指向元素大于flag或者high指向元素小于flag,需要赋值元素,则切换移动的指针并移动(被赋值的位置不用比较,肯定符合要求),否则继续移动当前指针),直到low high位置重合为止,此时将flag赋值到该位置即可。

具体步骤:

以 18 53 8 12 1 47 6 23为例,以18为flag,具体步骤如下(蓝色代表low,红色代表high)

grafana排序 gh排序_函数返回

  1. 先看high,因为23 大于18,high继续左移

grafana排序 gh排序_grafana排序_02

2.此时high->6,因为6<18,所以将6赋给low对应的值,并移动low(因为赋值过后low的值变成6,6一定小于18,所以直接移动low即可,后面以此类推)

grafana排序 gh排序_快速排序_03

3.此时low->53,因为53>18,所以将53赋值给high对应的值并移动high

grafana排序 gh排序_快速排序_04

4.此时high->47,因为47>18,所以继续左移high

grafana排序 gh排序_赋值_05

5.此时high->1,因为1<18,所以将1赋给low对应的值,并右移low

grafana排序 gh排序_函数返回_06

6.此时low->8,因为8<18,继续右移low

grafana排序 gh排序_快速排序_07

7.此时low->12,因为12<18,继续右移low

8.此时low high重合,将flag值放到该下标即可。

grafana排序 gh排序_c语言_08

这样,找到了第一个中间元素,左边的元素一定不大于flag,右边的元素一定不小于flag。

以此类推,处理flag左边的部分和flag右边的部分即可,直到长度为1停止。

代码如下(flag代表每次选出的中间数,左边不大于flag,右边不小于flag):

int sort(int *s,int low,int high)
{
    int flag=s[low];
    while(low<high)//high low重合停止
    {
        while(low<high&&flag<=s[high])
        {
            high--;//flag不大于high指向元素,high继续左移
        }
        if(low<high)
        {//遇到需要放到左边元素,将high指向元素直接赋值到low位置
            s[low]=s[high];
        }
//有交换操作后开始移动L
        while(low<high&&flag>=s[low])
        {
            low++;//flag不小于low指向元素,low继续右移
        }
        if(low<high)
        {
//遇到需要放到右边元素,将low指向元素直接赋值到high位置
            s[high]=s[low];
        }
//交换操作之后继续执行high左移操作直到high low重合
    }
    s[high]=flag;//将flag放到high low重合位置
    return high;
}
int quick_sort(int *s,int low,int high)
{
    int ret=0;
    if(low<high)//序列长度为1作为递归出口,此时low>=high
     {
         ret=sort(s,low,high);//函数返回了low high重合位置
         quick_sort(s,ret+1,high);
         quick_sort(s,low,ret-1);
     }
}