• 快速排序思想的应用求数组中第k小的数


    1问题定义

      加入数组arr中数据是:4,0,1,0,2,3,那么第三小的元素是1,问怎么样快速的求出这个第k小的数。

    2.解决方案

    解法一:

      利用STL中快速排序把数组进行排序,然后数组下标是k-1的就是我们要求的第k小的元素了,这种情况的时间复杂度接近于O(n*logn)。但是回头想一想这个算法是把数组进行了全排序,而我们只是要找到数组中第k小的数,这显然是“杀猪用了牛刀”。当然了时间复杂度较高也是正常的。

    解法二:

      想一想快速排序的思想:将数组中某一个元素m作为划分依据(我们假设为第一个元素,即m = arr[0]),遍历一遍数组,使得数组的格局变成这样的三个部分:(1)m前面的元素 (2)m  (3)m后面的元素。其中m前面的元素小于m,m后面的元素大于m,这样找第k小的数正好可以借鉴这个思想,即:

    1、若m前面的元素个数大于k,则第k小的数一定在m前面的元素中,这时我们只需要继续在m前面的元素中搜索第k小的数;

    2、若m前面的元素个数小于k,则第k小的数一定在m后面的元素中,这是我们只需要继续在m后面的元素中搜索第k-s小的数,其中s是m前面的元素个数。

    下面给出代码:(在vc6.0下测试)

     1 #include <iostream.h>
     2 
     3 #define MAX_SIZE 100
     4 
     5 int Biger[MAX_SIZE];
     6 int Smaller[MAX_SIZE];
     7 
     8 int Select_kth_Small(int arr[],int n,int k)
     9 {
    10     if(n == 1)
    11         return arr[0];
    12     int b = 0,s = 0,t = arr[0],temp_n,temp_k;
    13     int temp[MAX_SIZE];
    14     for(int i = 1 ; i < n ; i++)//遍历集合
    15     {
    16         if(arr[i] > t)
    17             Biger[b++] = arr[i]; //如果当前元素比t大,就将当前元素加入Biger[]
    18         else
    19             Smaller[s++] = arr[i];//反之就加入到Smaller,这里没有考虑set[0]
    20     }
    21     if(b == 0)
    22     {
    23         Biger[b++] = t;//if...else主要是为了防止t大于或小于其他所有元素的情况
    24     }
    25     else
    26     {
    27         Smaller[s++] = t;
    28     }
    29     //如果Smaller集合中的元素个数大于K,说明第K小的元素必在其中
    30     //否则一定在Biger中,且应该是Biger集合中第k-r小的元素
    31     //更新相应的变量
    32     if(s >= k)
    33     {
    34         temp_n = s;
    35         temp_k = k;
    36         for(i=0;i<temp_n;i++)
    37         {        
    38             temp[i] = Smaller[i];
    39         }
    40     }        
    41     else
    42     {
    43         temp_n = b;
    44         temp_k = k-s;
    45         for(i=0;i<temp_n;i++)
    46         {
    47             temp[i]=Biger[i];    
    48         }
    49     }
    50     return Select_kth_Small(temp,temp_n,temp_k);
    51 }
    52 
    53 int main()
    54 {
    55     int arr[]={4,0,1,0,2,3};
    56     int ans = Select_kth_Small(arr,6,3);
    57     cout<<"在数组arr[]={4,0,1,0,2,3}中,第3小的数是:"<<ans<<endl;
    58     return 0;
    59 }

    这个代码多用了较多的辅助空间,为的是不改变原来的数组的元素的顺序。不知道这个代码有什么漏洞没有,大家帮帮找找。谢谢喽……

    学习中的一点总结,欢迎拍砖哦^^

  • 相关阅读:
    Promise
    includes()
    常见的数组去重方法
    concat()
    面试感想
    常见的前端面试题
    让div水平垂直居中的几种方法
    实现斐波拉契的几种方法
    使用lib-flexible
    什么是token
  • 原文地址:https://www.cnblogs.com/BeyondAnyTime/p/2591207.html
Copyright © 2020-2023  润新知