也論從1億個整數中找出最大的1萬個(下)

2021-05-22 01:04:25 字數 2101 閱讀 7625

改寫adjust_heap函式,讓要插入值與插入點的孩子節點進行比較判斷。

template < class distance,class tp, class compare>

inline void adjust_heap( tp *first, distance holeindex, distance len, distance distindex,tp val,compare cmp)

//左節點大於等於val,則插入並返回

if ( *(first + secondchild) >= val )

*(first + holeindex) = *(first + secondchild); //holeindex 節點寫為較大子節點

holeindex = secondchild; //holeindex設為較大子節點的索引,繼續迴圈

secondchild=2*(secondchild+1);

}//holeindex節點沒有右子節點並且左子節點大於val

//左子節點上移,val寫入左子節點的位置

if (secondchild == len && cmp( val, *(first+secondchild-1) ) )

//否則holeindex寫為val

else *(first + holeindex)=val;

}程式就變為:solution_2

make_heap(bigarr,bigarr+res_arr_size,greater_equal());

for(int j=res_arr_size;j( ) ); );

} }

用 (int)res_arr_size,是因為res_arr_size定義為const unsigned int ,所以要強制轉換下。

隨機情況下solution_2為483 毫秒左右比solution_1快了10%,陣列有序情況下為38秒左右,比solution_1快了80%。

沒有出現是solution_1速度3倍的原因,我分析了下,

1. 在隨機亂序情況下,一次完整遍歷要300毫秒左右,所以沒多大差別。

2. 在陣列完全有序(由小到大)時,在adjust_heap未呼叫push_heap時用時o(logm),呼叫的push_heap根本就沒有遞迴深入到根節點處。在pop_heap和push_heap一段時間後,每層元素亂序但每個元素都大於下一層的元素。push_heap從來就沒有遞迴到根節點!但模板例項化和函式巢狀呼叫耗了大量的時間。

我再將模板具體例項化solution_3

inline void adjust_heap(int * first, int holeindex, int len, int distindex,int val)

//左節點大於等於val,則插入並返回

if ( *(first + secondchild) >= val )

*(first + holeindex) = *(first + secondchild);//holeindex 節點寫為較大子節點

holeindex = secondchild;//holeindex設為較大子節點的索引,繼續迴圈

secondchild=2*(secondchild+1);

}//holeindex節點沒有右子節點並且左子節點大於val

//左子節點上移,val寫入左子節點的位置

if (secondchild == len && *(first+secondchild-1) < val)

//否則holeindex寫為val

else *(first + holeindex)=val;

}程式中呼叫

make_heap(bigarr,bigarr+res_arr_size,greater_equal());

for(int j=res_arr_size;j

測試了下,隨機情況時間為480毫秒左右,陣列從小到大有序時為18.8秒,比solution_1快了近3倍。綜合solution_1,solution_2,看來在大量需要重複執行的地方,執行時模板例項化和函式巢狀呼叫的耗時不可小覷,呵呵

總結:1.stl的確是個好東西,又快又安全又方便。

2.在函式反覆呼叫的地方,如果要考慮效率,則應慎重些。

以上均是個人主觀遐想,歡迎拍磚。

一道筆試題 從1億個整數中找出最大的一萬個

今天看到一篇賴永浩大牛的部落格,由一道筆試題目談演算法優化。http blog.csdn.net lanphaday archive 2008 12 19 3547776.aspx 題目原題是從10億個浮點數中找出最大的一萬個,賴的文章主要是講如何去優化演算法,並不是側重在這道題目,所以對其進行了簡...

從1億個ip中找出訪問次數最多的IP

問題一 怎麼在海量資料中找出重複次數最多的乙個 演算法思想 方案1 先做hash,然後求模對映為小檔案,求出每個小檔案中重複次數最多的乙個,並記錄重複次數。然後找出上一步求出的資料中重複次數最多的乙個就是所求 如下 問題二 日誌中記錄了使用者的ip,找出訪問次數最多的ip。演算法思想 ip位址最多有...

談從10億個數中找出前10萬個最大的

10億個浮點數大概佔據3g左右的空間,因此全部一次性讀入記憶體目前在個人pc上是不太現實的。本次討論不考慮記憶體等等,只考慮演算法。如果一次性比較排序,然後輸出前面最大的10w個,那麼眾所周知,演算法的時間複雜度不下於o n lgn 此處的n為數的個數 10億 如果用堆排序,由於堆排序像合併排序而不...