• Select(快速选择顺序统计量)原理及C++代码实现


    SELECT算法利用快排中的partition思想来进行无序数组的快速选择。

    寻找第i个顺序统计量可以简单理解为寻找第i小的元素。

    该算法通过为partition选择一个好的主元,来保证Partition得到一个好的划分。

    当然partition需要进行一些修改,把划分的主元也作为输入参数。

    代码如下:(仅供参考)

     1 void InsertionSort(int * const begin, int * const end) {
     2     int i, j, key;
     3     for (i = 1; i < begin - end; ++i) {
     4         key = *(begin + i);
     5         for (j = i - 1; j >= 0 && (*(begin + j) > key); --j) {
     6             *(begin + j + 1) = *(begin + j);
     7         }
     8         *(begin + j + 1) = key;
     9     }
    10 }
    11 int Partition(int * const begin, int * const end, int x) {
    12     int i = -1;
    13     for (int j = 0; j < (end - begin); ++j) {
    14         if (*(begin + j) < x) {
    15             ++i;
    16             swap(*(begin + i), *(begin + j));
    17         }
    18         else if (*(begin + j) == x && j != (end - begin - 1)) {
    19             swap(*(begin + j), *(end - 1));
    20             --j;
    21         }
    22     }
    23     ++i;
    24     swap(*(begin + i), *(end - 1));
    25     return i;
    26 }
    27 
    28 //返回第k小的元素,要求输入元素互异,最坏情况下时间复杂度为线性
    29 int Select(int * const begin, int * const end, int k) {
    30     if (end - begin == 1)
    31         return *begin;
    32     int n = end - begin;
    33     int groupnum = n / 5; //groupnum个组,每组五个数
    34     int medium[10000]; //因小于50000个数
    35 
    36     int i, j, t = groupnum;
    37     for (i = 0, j = 0; t--; i += 5) {
    38         InsertionSort(begin + i, begin + i + 5);
    39         medium[j++] = *(begin + i + 2);
    40     }
    41     if (n > (groupnum * 5)) {
    42         InsertionSort(begin + i, end);
    43         medium[j++] = *(begin + i + (end - begin - i) / 2);
    44     }
    45 
    46     int x = Select(medium, medium + j, (j + 1) / 2);
    47     int m = Partition(begin, end, x) + 1;
    48     if (m == k)
    49         return x;
    50     else if (m > k)
    51         return Select(begin, begin + m - 1, k);
    52     else
    53         return Select(begin + m, end, k - m);
    54 }
  • 相关阅读:
    Flex 布局
    前端跨域之jsonp
    vs code 自定义代码片段
    vue中使用axios进行http通信
    Table边框合并
    getElementsBy 系列方法相比querySelector系列的区别
    vue中watch简单使用
    png图标任意赋色
    pc端与移动端适配解决方案之rem
    Express post请求无法解析参数的原因
  • 原文地址:https://www.cnblogs.com/yxsrt/p/12193807.html
Copyright © 2020-2023  润新知