找出具有n個元素的集合中最大的兩個元素,要求比較次數儘可能少(三種算法的思考)...

http://blog.csdn.net/will_lee_buaa/article/details/12884989

題目:給定具有n個元素的集合,找出最大的兩個元素,算法要求比較次數儘可能少

 

這個題目要做出來很簡單,但是要找出比較次數儘可能少的算法也不是件容易的事情。

對於這個題目,目前有三種方法比較流行。

第一種:對集合掃描兩遍(當然也可以掃描一遍,同時最大和第二大元素,但花費的比較次數和掃描兩遍,在最壞情況下是一樣的),第一遍找出最大的元素,第二遍從剩餘的元素中找出最大的元素,即整個集合的第二大元素。兩遍掃描需要的比較次數爲2*n-3次

 

第二種:將集合每兩個元素一組,分成n/2組,組內兩個元素先進行比較,初始化兩個元素,max1,max2,代表當前最大和第二大元素,然後從第一組開始,讓max1和max2,依次和每組進行比較,並更新max1和max2,得到最終的整個集合的max1和max2。整個過程需要的比較次數爲3*n/2次

 

第三種:此種方案,似乎被幾乎所有人認爲是最好的方案,可是事實卻是相反的!下面進行第三種方案的分析:

第一步:將集合每兩個元素一組,分成n/2組,組內元素進行比較,選出比較大的那個元素。

第二步:將第一步選出的n/2個元素遞歸使用第一步的處理方式。直到選出集合中最大的元素。

第三步:從和最大元素比較過的元素中,選出最大的元素即爲第二大元素。

從第三步可以看出,我們需要開闢一塊空間,在每一步中記錄和每一個元素比較過的元素集合。因爲,在第二部執行結束之前,我們並不知道最大元素是哪個元素。從第一步和第二步我們可以想象出來,整個比較過程像一棵二叉樹,先從n個子節點開始,一層一層比較,一直到根節點(最大元素)。兩個子節點的父節點是兩個子節點中較大的那個元素。因此我們可以得到和最大元素比較過的元素的個數等於樹的高度,即lgn,所以第三步需要的比較次數爲lgn-1,而第一步和第二步需要的比較次數爲n-1次,所以總的比較次數爲n+lgn-2次,似乎比第一種和第二種方案要好些。

但是,第三種方案需要一塊內存空間記錄和每一個元素比較過的元素,這個內存空間用數組表示是個二維數組(可以用鏈表等其他數據結構表示,不影響後面的分析結果),A[1..n][1..lgn],由於n是要處理元素的規模,因此,二位數組需要動態申請,並初始化,這需要花費nlgn的時間!!從這裏就可以看出來,第三種方案屬於撿了芝麻,丟了西瓜!因此,此種方案是不可取的。

我們可以嘗試着對第三種方案進行優化,能不能把A[1..n][1..lgn]二維數組優化爲一維數組。

我們可以在算法最開始的時候對集合掃描一遍,找到最大元素,這個時候,我們只需要一個大小爲lgn的一維數組來記錄和最大元素比較過的元素了,但是對集合掃描一遍需要n-1次比較,所以優化後的總的比較次數爲2*n+lgn-3次,還是比前兩種方案要差!!

 

注:在我們專注於比較次數的時候,忽略了賦值操作,在三種算法中賦值操作的次數不比比較次數要少,但是因爲三種算法的賦值操作次數差不多,上面的分析方法就忽略了賦值操作的影響。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章