查找第K小的元素(利用中位数线性时间选择)(C)

Posted SaraMorning

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了查找第K小的元素(利用中位数线性时间选择)(C)相关的知识,希望对你有一定的参考价值。

找任意第k个小的元素

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <ctime>
  4 #include <iostream> 
  5 using namespace std; 
  6 
  7 template <class Type>
  8 void Swap(Type &x,Type &y);
  9 
 10 inline int Random(int x, int y);
 11 
 12 template <class Type>
 13 void BubbleSort(Type a[],int p,int r);
 14 
 15 template <class Type>
 16 int Partition(Type a[],int p,int r,Type x);
 17 
 18 template <class Type>
 19 Type Select(Type a[],int p,int r,int k);
 20 
 21 int main()
 22 {
 23     //初始化数组
 24     int a[100];
 25 
 26     //必须放在循环体外面
 27     srand((unsigned)time(0));
 28 
 29     for(int i=0; i<100; i++)
 30     {
 31         a[i] = Random(0,500);
 32         cout<<"a["<<i<<"]:"<<a[i]<<" ";
 33     }
 34     cout<<endl;
 35 
 36     cout<<"第83小元素是"<<Select(a,0,99,83)<<endl;
 37 
 38     //重新排序,对比结果
 39     BubbleSort(a,0,99);
 40 
 41     for(int i=0; i<100; i++)
 42     {
 43         cout<<"a["<<i<<"]:"<<a[i]<<" ";
 44     }
 45     cout<<endl;
 46 }
 47 
 48 template <class Type>
 49 void Swap(Type &x,Type &y)
 50 {
 51     Type temp = x;
 52     x = y;
 53     y = temp;
 54 }
 55 
 56 inline int Random(int x, int y)
 57 {
 58     int ran_num = rand() % (y - x) + x;
 59     return ran_num;
 60 }
 61 
 62 //冒泡排序
 63 template <class Type>
 64 void BubbleSort(Type a[],int p,int r)
 65 {
 66     //记录一次遍历中是否有元素的交换   
 67     bool exchange;  
 68     for(int i=p; i<=r-1;i++)  
 69     {  
 70         exchange = false ;  
 71         for(int j=i+1; j<=r; j++)  
 72         {  
 73             if(a[j]<a[j-1])  
 74             {  
 75                 Swap(a[j],a[j-1]); 
 76                 exchange = true;  
 77             }   
 78         }   
 79         //如果这次遍历没有元素的交换,那么排序结束   
 80         if(false == exchange)  
 81         {
 82             break ;  
 83         }
 84     }
 85 }
 86 
 87 template <class Type>
 88 int Partition(Type a[],int p,int r,Type x)
 89 {
 90     int i = p-1,j = r + 1;
 91 
 92     while(true)
 93     {
 94         while(a[++i]<x && i<r);
 95         while(a[--j]>x);
 96         if(i>=j)
 97         {
 98             break;
 99         }
100         Swap(a[i],a[j]);
101     }    
102     return j;
103 }
104 
105 
106 template <class Type>
107 Type Select(Type a[],int p,int r,int k)
108 {
109     if(r-p<75)
110     {
111         BubbleSort(a,p,r);
112         return a[p+k-1];
113     }
114     //(r-p-4)/5相当于n-5
115     for(int i=0; i<=(r-p-4)/5; i++)
116     {
117         //将元素每5个分成一组,分别排序,并将该组中位数与a[p+i]交换位置
118         //使所有中位数都排列在数组最左侧,以便进一步查找中位数的中位数
119         BubbleSort(a,p+5*i,p+5*i+4);
120         Swap(a[p+5*i+2],a[p+i]);
121     }
122     //找中位数的中位数
123     Type x = Select(a,p,p+(r-p-4)/5,(r-p-4)/10);
124     int i = Partition(a,p,r,x);
125     int j = i-p+1;
126     if(k<=j)
127     {
128         return Select(a,p,i,k);
129     }
130     else
131     {
132         return Select(a,i+1,r,k-j);
133     }
134 }

 

 

h

以上是关于查找第K小的元素(利用中位数线性时间选择)(C)的主要内容,如果未能解决你的问题,请参考以下文章

线性查找算法(BFPRT)

最坏情况为线性时间的选择算法

选择问题(分治策略)

求C语言线性时间选择

数据结构 数组笔记

中位数和顺序统计量