第k小數1
阿新 • • 發佈:2018-02-14
一個 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 16void 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