算法探究:线性时间选择问题
一.什么是線性時間選擇問題
前幾天,女票問到了快速排序,然后我看了一下代碼,發現不對呀,為什么連基本的遞歸都沒有,后來仔細看了整個程序之后,發現,這個程序并不是普通的快速排序,而這也就引出了今天要講的問題,線性時間選擇問題,其實它也就是隨機化的快速排序,以求加快效率,最快求解。
二.大體思路
RandomizedSelect算法,因為該算法是想要求解在一個序列中某一個等級大小的數,那么這個算法的大體思路其實就是隨機選取基準元素,根據基準元素進行分區,小的分在左邊,大的分在右邊,每次分完之后返回基準元素所在數組中的索引,同時比較等級,小的話在左邊查找,大的話在右邊查找,那么這樣說的話大家是不是又想到了快速排序算法,是不是特別熟悉呢。
三.具體實現
談及具體實現的話,我還是先把代碼貼上來然后一點一點地分析。
int RandomizedSelect(int a[],int low,int high,int k) {if(low==high)return a[low];int i=RandomizedPartition(a,low,high);int j=i-low+1;if(k<=j)return RandomizedSelect(a,low,i,k);elsereturn RandomizedSelect(a,i+1,high,k-j); }這就是其中最核心的部分。
03,04:和快排類似,倘若low==high,那么說明基準點已經到了我們需要的等級的位置,直接返回當前值。
05:假如不相等,那么就得重新分區。
06--10:重新分區之后,就得根據基準元素返回的索引考慮接下來往哪邊尋找。
接下來是隨機選取基準元素的函數
int RandomizedPartition(int a[],int low,int high) {Random rm = new Random();int i = rm.Next(low,high);Swap(a[i],a[low]);return Partition(a,low,high); }前兩句就是在新的分區里面尋找新的隨機基準點,在這里我們把隨機選取的基準點和第一個元素交換,因為后面分區的時候一直以第一個元素為基準,后兩句就是重新分區。
最后就是分區函數,其實這里就用到了快排
int Partition(int a[],int low,int high) {int i=low,j=high+1;int x=a[low];while(true){while(a[++i]<x&&i<high);while(a[--j]>x);if(i>=j) break;Swap(a[i],a[j]);}a[low]=a[j];a[j]=x;return j; }
相信這里就不用過多解釋了,很容易理解。
最后附上整個實例。
#include<iostream> #include<cstdlib> #include<time.h> using namespace std; void Swap(int &a,int &b) { int tmp=a; a=b; b=tmp; } int Partition(int a[],int low,int high) { int i=low,j=high+1; int x=a[low];while(true){while(a[++i]<x&&i<high);while(a[--j]>x);if(i>=j) break;Swap(a[i],a[j]); } a[low]=a[j];a[j]=x; return j; } int RandomizedPartition(int a[],int low,int high) { Random rm = new Random();int i = rm.Next(low,high);Swap(a[i],a[low]); return Partition(a,low,high); } int RandomizedSelect(int a[],int low,int high,int k) { if(low==high) return a[low]; int i=RandomizedPartition(a,low,high); int j=i-low+1; if(k<=j) return RandomizedSelect(a,low,i,k); else return RandomizedSelect(a,i+1,high,k-j); } /* 測試 */ int main() { int a[]={4,7,9,5,8,3,0,1}; int k=2; int result=RandomizedSelect(a,0,7,k); cout<<"第"<<k<<"小的元素是"<<result<<endl; return 0; }
四.總結
首先要強調的是,RandomizeSelect算法,最好能夠達到O(n)的時間復雜度,這時很不錯的,另外最壞也是O(n*n),而不是像一些普通算法,平均復雜度是O(n*n),其次呢,該算法跟數據的準備還是有比較大的關系的,這個我們之后再另外寫一篇好好敘述。總的說來呢,我主要是看到之后耳目一新,自己實現了一下,其實我完全是算法方面的小白,如果有錯誤還希望指正。
? email: wuzhicheng@bjfu.edu.cn ?
? 謝謝!
總結
以上是生活随笔為你收集整理的算法探究:线性时间选择问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Glide 加载圆角图片(解决设置圆角后
- 下一篇: [html] 对一个元素设置浮动后,它