选择问题(选出第i个最小元素)

通过分治法解决的分析(还有其他方法解决选择问题如使用

1 同快速排序一样,对输入的数组进行递归分解

   不同的是:快速排序会递归处理分解的两边,而选择问题只处理需要的一边

2 选择问题的期望时间代价为Θ (n)  (平均性能)

3 选择问题一般思路

    a. 随机选取一个key

    b. 进行区域划分,比key小的在左边,比key大的在右边

    c. key的下标与 (第i个最小元素的下标)比较,分别处理3种情况

          相等:    即为需要选择的元素 

       i<key:      说明第i个最小元素在划分区域的左边,进行递归分解左边的区域   

       i>key:      说明第i个最小元素在划分区域的右边,进行递归分解右边的区域,[注意需要考虑

        此时第i个元素在区域右边为第i-k(key的下标)个最小元素]

 1 #include <iostream>
 2 using namespace std;
 3 
 4 //交换数据
 5 void Swap(int array[], int i, int j)
 6 {
 7     int temp = array[i];
 8     array[i] = array[j];
 9     array[j] = temp;
10  }
11 
12 //选择问题,index 表示选择第i个最小元素
13 int RandomSelect(int array[], int size, int index)
14 {
15     if (size <=1)
16     {
17         return array[size-1];   //只有一个元素时即为需要选择的元素
18     }
19 
20     int key = 0;
21     Swap(array, 0, rand()%size);  //随机化取样,获得关键值key并与array[0]交换
22 
23     //进行区域划分,分别与key比较,小于key的都在左边,大于key的都在右边
24     for (int i=1; i<size; ++i)
25     {
26         if (array[i] < array[0])
27         {
28             Swap(array, ++key, i);
29         }
30     }
31     Swap(array, 0, key);//关键值key回到正确的位置
32     
33     if (key == index-1) //相等,即为需要选择的第i个元素
34     {
35         return array[key];
36     }
37     else if (index-1 < key) //index小于key,即第i个元素在划分区域的左边
38     {
39         return RandomSelect(array, key, index);
40     }
41     else//index大于key,即第i个元素在划分区域的左边,注意同时更新index-key-1(去除key本身)
42     {
43         return RandomSelect(array+key+1, size-key-1, index-key-1);
44     }
45 }
46 
47 void main()
48 {
49 
50     int Array[10] = {4, 1, 3, 2, 6, 9, 10, 5, 8, 7};
51 
52     int i = 10;
53     cout << "" << i <<"个最小元素: " 
54          << RandomSelect(Array, 10, i) << endl;
55 
56     system("pause");
57 }

(转载请注明作者和出处^_*  Seven++ http://www.cnblogs.com/sevenPP/  )

原文地址:https://www.cnblogs.com/sevenPP/p/3651110.html