生活随笔
收集整理的這篇文章主要介紹了
线性时间选择
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
問題:給定線性序集中n個元素和一個整數k,1≤k≤n,要求找出這n個元素中第k小的元素。(這里給定的線性集是無序的)。(如果將這個線性集先排好序,則排在第k個位置的元素即為要找的元素)
方法:線性時間選擇隨機劃分法可以模仿隨機化快速排序算法設計。基本思想是對輸入數組進行遞歸劃分,與快速排序不同的是,它只對劃分出的子數組之一進行遞歸處理。
可以按以下步驟找到滿足要求的劃分基準:
將n個輸入元素劃分成n/5(向上取整)個組,每組5個元素,最多只可能有一個組不是5個元素。用任意一種排序算法,將每組中的元素排好序,并取出每組的中位數,共n/5(向上取整)個。
遞歸調用select來找出這n/5(向上取整)個元素的中位數。如果n/5(向上取整)是偶數,就找它的2個中位數中較大的一個作為劃分基準。
思考草圖:
(每一組進行排序,最后不足5個的忽略)
————————————————————————————
(找出每一組的中位數)
————————————————————————————
(把中位數提出來)
————————————————————————————————————
(找到中位數的中位數)
————————————————————————————————————
(交換位置作為“軸”,借鑒快速排序)
————————————————————————————
(找到k)
#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std
;int partition(int a
[], int p
, int r
){int i
= p
;int j
= r
+ 1;int x
= a
[p
]; while(true){while(a
[++i
] < x
&& i
< r
) ;while(a
[--j
] > x
) ;if(i
>= j
)break;swap(a
[i
], a
[j
]);}a
[p
] = a
[j
];a
[j
] = x
;return j
;
}int partition(int a
[], int p
, int r
, int x
){ int i
= p
-1;int j
= r
+ 1;while(true){while(a
[++i
] < x
&& i
< r
) ;while(a
[--j
] > x
) ;if(i
>= j
)break;swap(a
[i
], a
[j
]);}a
[p
] = a
[j
];a
[j
] = x
;return j
;
}void quickSort(int a
[], int p
, int r
){if(p
< r
){int q
= partition(a
, p
, r
);quickSort(a
, p
, q
- 1); quickSort(a
, q
+ 1, r
); }
}int select(int a
[], int p
, int r
, int k
){if(r
- p
< 75) {quickSort(a
, p
, r
); return a
[p
+k
- 1];}for(int i
= 0; i
<= (r
-p
-4) / 5; i
++){ quickSort(a
, p
+i
*5, p
+i
*5+4); swap(a
[p
+i
], a
[p
+i
*5+2]); }int x
= select(a
, p
, p
+(r
-p
-4) / 5, (r
-p
-4) / 10); int pivot
= partition(a
, p
, r
, x
);int j
= pivot
-p
+ 1;if(k
<= j
)return select(a
, p
, pivot
, k
);elsereturn select(a
, pivot
+ 1, r
, k
- j
);
}int main(){int a
[100];srand((int)time(0)); for(int i
= 0; i
< 100; i
++){a
[i
] = rand() % 100;}int k
;cout
<< "please input k: " << endl
; cin
>> k
;cout
<< select(a
, 0, 99, k
) << endl
;for(int i
= 0; i
< 100; i
++){cout
<< a
[i
] << " ";} cout
<< endl
<< "-------------檢驗組----------"<< endl
;quickSort(a
, 0, 99);for(int i
= 0; i
< 100; i
++){cout
<< "a[" << i
<< "]="<< a
[i
] << " ";} }
總結
以上是生活随笔為你收集整理的线性时间选择的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。