快速排序相关

102 阅读1分钟

快速排序

快速排序:

快排运用了分治的思想,分为三步:

  1. 分成子问题
  2. 递归处理子问题
  3. 子问题合并 其中核心思想是:选定一个数x,让待排数组中x左边的数均小于x,X右边的数均大于X,此时x会放在最终位置(该位置在最后不会改变)上,进行递归,缩小l和r之间的距离使得每一个数的左边一个数比它小,右边一个数比它大,即达到了排序的效果,代码如下。
void quick_sort(int q[], int l, int r)
{
    //递归结束条件
    if(l >= r) return;
    
    int x = q[(l + r) >> 1];
    int i = l - 1, j = r + 1;
    while(i < j)
    {
        do i ++; while(q[i] < x);//会让i停在>=x的位置
        do j --; while(q[j] > x);//会让j停在<=x的位置
        if(i < j) swap(q[i], q[j]);
    }
    quick_sort(q, l, j);
    quick_sort(q, j + 1, r);
}

例如:

微信图片_20220601120210.jpg

快速排序的时间复杂度为:O(nlogn)O(nlogn) 稳定性:不稳定

第k个数

给定一个长度为n的整数数列,以及一个整数k,请用快速选择算法求出数列从小到大排序后的第k个数。
本体可以利用快排的性质,即在经过一趟排序后会确定选定的数的最终位置j,然后再判断K在j的左边还是右边,在左边就可以只递归左边,在右边就只需要递归右边。

int quick_sort(int q[], int l, int r, int k)
{
    if(l >= r) return q[l];
    
    int x = q[(r + l) >> 1], i = l - 1, j = r + 1;
    while(i < j)
    {
        do i ++; while(q[i] < x);
        do j --; while(q[j] > x);
        if(i < j) swap(q[i], q[j]);
    }
    int s1 = j - l + 1;
    //int s2 = r - j;
    if(k <= s1) return quick_sort(q, l, j, k);
    else return quick_sort(q, j + 1, r, k - s1);
}