2022-01-26 查找中位数,用快排的思想

如果查找中位数,最简单的方法就是排序取中间的数。

扩展而来就是寻找最小的第k个数。

那么就不一定用排序,或者只需要一部分排序。

快排的partition算法可以将数组分为比某个数大和比某个数小的两部分,这不就是最小的第k个数么。

而中位数就是前后数量相等而已。

算法逻辑:

将数组分为大于某数和小于某数两部分,某数的位置与K进行比较,如果小于K,那么K在大于某数的部分,重新在大于某数的部分继续分割,直到切割的数的位置等于K。

代码如下:

#ifndef MIDNUM
#define MIDNUM

#include 
#include 
#include 

struct middelNum
{
    int midnum(std::vector<int> &arr, int k)
    {
        std::shuffle(arr.begin(), arr.end(), std::mt19937(time(0)));
        int lo = 0;
        int hi = arr.size() - 1;
        while (hi > lo)
        {
            int j = partition(arr, lo, hi);
            if (j == k)
            {
                return arr[k];
            }
            else if (j > k)
            {
                hi = j - 1;
            }
            else if (j < k)
            {
                lo = j + 1;
            }
        }
        return arr[k];
    }

private:
    int partition(std::vector<int> &arr, int lo, int hi)
    {
        int i = lo;
        int j = hi + 1;
        int v = arr[lo];
        while (1)
        {
            while (arr[++i] < v)
            {
                if (i == hi)
                {
                    break;
                }
            }
            while (v < arr[--j])
            {
                if (j == lo)
                {
                    break;
                }
            }
            if (i >= j)
            {
                break;
            }
            std::swap(arr[i], arr[j]);
        }
        std::swap(arr[lo], arr[j]);
        return j;
    }
};

#endif

你可能感兴趣的:(笔记,排序算法,算法,c++)