1. 程式人生 > >第k小數1

第k小數1

一個 mes for std 無序 oid spa 調整 iostream

對於給定的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 }

第k小數1