• 第k小数1


    对于给定的n个元素的无序数组,要求从中找出第k小的元素

    二分法+快速排序

    例如一列由10个元素组成的数组:[5, 7, 1, 2, 3, 9, 8, 10,  4, 6],假设找出k = 4 的元素。

    将第一个元素5作为参照物, 将比5小的数放在5的左边,比5大的数放在5的右边,则数组第一次调整为【2,1,4,3】5【10,9,8,7】。

    比5小的数由4个,所以将搜索范围缩小到5的左边数组即【2,1,4,3】舍弃右边的数组。

    以2为参照物, 将比2小的数字放在2的左边,比2大的数字放在2的右边。则数组的第二次调整为:【1】2【4,3】。

    可以看出,2为数组中第2小的数字,所以将搜索范围缩小到2的右边数组【4,3】,舍弃左边的数组。

    最后一次找到第4小的数字为4。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cstdio>
     5 #include<algorithm>
     6 using namespace std;
     7 int a[100001], b[100001];
     8 int i, j, m, k, l;
     9 
    10 void Swap()
    11 {
    12     swap(a[i], a[j]);
    13     swap(i, j);
    14 }
    15 
    16 void Operation(int START, int END)
    17 {
    18     i = START;
    19     j = END;
    20     while(i != j)
    21     {
    22         if(i < j)
    23         {
    24             if(a[i] > a[j])
    25                 Swap();
    26             else
    27                 j--;
    28         }
    29         else
    30         {
    31             if(a[i] < a[j])
    32                 Swap();
    33             else
    34                 j++;
    35         }
    36     }
    37     if(i < k)
    38         Operation(i + 1, END);
    39     else if(i == k)
    40     {
    41         for(l = 1; l <= m; l++)
    42         {
    43             if(b[l] == a[i])
    44             {
    45                 cout << l << endl;
    46                 break;
    47             }
    48         }
    49     }
    50     else
    51         Operation(START, i - 1);
    52 }
    53 int main()
    54 {
    55     cin >> m >> k;
    56     for(int i = 1; i <= m; i++)
    57     {
    58         cin >> a[i];
    59         b[i] = a[i];
    60     }
    61     Operation(1, m);
    62     return 0;
    63 }

    如果在线性时间内找到划分的基准,则可以在最坏情况下复杂度为O(n)时找到第k小的数。

    方法如下

    (1)将数组a五个数为一组,分为【n/5】个组。

    (2)对【n/5】个组的数进行组内排序,采用冒泡排序等任何方法均可。

    (3)选择每组的中位数,将这些中位数交换到数组的最前面,此时a[0 ~(end - start)/ 5 - 1]中存的就是这些中位数。

    (4)对a[0 ~(end - start)/ 5 - 1]个中位数进行排序,取出排序后这些中位数的中位数x,则x就是需要的划分标准。

    (5)以x为基准再次进行二分,比较,递归寻找即可。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cstdio>
     5 #include<algorithm>
     6 using namespace std;
     7 int a[100001], b[100001];
     8 int i, j, m, k, l;
     9 int cmp(int x, int y)
    10 {
    11     return x < y;
    12 }
    13 void Swap()
    14 {
    15     swap(a[i], a[j]);
    16     swap(i, j);
    17 }
    18 
    19 void Operation(int START, int END)
    20 {
    21     i = START;
    22     j = END;
    23     while(i != j)
    24     {
    25         if(i < j)
    26         {
    27             if(a[i] > a[j])
    28                 Swap();
    29             else
    30                 j--;
    31         }
    32         else
    33         {
    34             if(a[i] < a[j])
    35                 Swap();
    36             else
    37                 j++;
    38         }
    39     }
    40     if(i < k)
    41         Operation(i + 1, END);
    42     else if(i == k)
    43     {
    44         for(l = 1; l <= m; l++)
    45         {
    46             if(b[l] == a[i])
    47             {
    48                 cout << l << endl;
    49                 break;
    50             }
    51         }
    52     }
    53     else
    54         Operation(START, i - 1);
    55 }
    56 int main()
    57 {
    58     cin >> m >> k;
    59     for(int i = 1; i <= m; i++)
    60     {
    61         cin >> a[i];
    62         b[i] = a[i];
    63     }
    64     for(i = 6; i <= m + 1; i = i + 5)
    65     {
    66         sort(a + i - 5, a + i, cmp);
    67     }
    68     for(i = 1; i <= m/5; i++)
    69         swap(a[i], a[i * 5 - 2]);
    70     sort(a + 1, a + i, cmp);
    71     swap(a[1], a[i / 2]);
    72     Operation(1, m);
    73     return 0;
    74 }
  • 相关阅读:
    IDEA运行测试错误Failed to resolve org.junit.platform:junit-platform-launcher
    mysql索引基本原理
    as3.0声音波形系列03_十组合
    as3.0声音波形系列02_六组合
    as3.0声音波形系列01_八组合
    FiltersEffect(效果)
    AS3 TransitionManager 自带特效类
    as3 判断鼠标移动方向
    AS3代码生成xml方法
    求线段的交点
  • 原文地址:https://www.cnblogs.com/CZT-TS/p/8447696.html
Copyright © 2020-2023  润新知