外部排序小結

       相對於內部排序算法,外部排序算法是在數據量很大的情況下才有的。當數據量很大時,不能一次性將數據放入內存進行內部排序算法,只能將數據分塊或者說分段,依次輸入到內存中進行排序,然後將他們排序好的再排序,最後實現總的排序。

       因此,外部排序用的方法就相對來說單一了——歸併排序。在外部排序實現歸併時,不僅歸併排序耗時間,而且需要進行外存的讀和寫,而由計算機知識知道訪問外存所需要的時間可是訪問內存的至少十幾倍。所以,提高外排的效率,就需要減少訪問外存的次數,可以進行n路平衡歸併而不只是兩兩歸併。

       經過分析可知,爲了使總歸併時間和歸併路數無關,可以利用敗者樹來實現。所謂敗者樹,是和勝者樹是對應的,勝者樹,是將二叉樹的子節點進行比較,“勝利的一方”放到父節點,然後和同一級的進行比較。而敗者樹,也是將勝者放到父節點,不過將敗者去和同級進行比較。爲了創建敗者樹,可以先創建一個一維數組,用來存放葉子節點的編號,而葉子節點也可以用一維數組表示,葉子節點內存放的數據是各路歸併樹依次投遞進來的數據,當某一個葉子節點被選爲最終的冠軍後,就選取該路的下一個值作爲其葉子節點,過程如下圖所示。

其中,ls數組用來存放敗者樹,ls[0]存放敗者樹的冠軍,就是最小那個,數組b用來存放5路歸併的數據。具體過程爲:b1和b2比較,b1大,存放其編號1到ls[3],然後b2用來和同級勝者的比較;b3和b4比較b4大,存放4在ls[4],b3就和b0比較,b3大,b0就和b2比較,b0大存放0,勝者爲b2,存放2到ls[0]。

       具體的算法實現如下所示:

創建敗者樹,這裏將數組ls初始值都設爲k,k爲歸併樹個數,這裏爲5,設定b[5]=-1,便於其他任何和它比較都是勝者

void CreateLoserTree(){
	 int i;
	 for(i=0; i<k; i++){
		 ls[i] = k;
	 }
	 for(i=k-1; i>=0; i--){
		 Adjust(ls, i);
	 }
}

調整樹,即將敗者記錄在父節點,勝者放到上一層去做比較

void Adjust(int ls[], int s){
	 int tmp = (s+k)/2;
	 while(tmp>0){
		 if(b[s] > b[ls[tmp]]){
			 int tt = s;
			 s = ls[tmp];
			 ls[tmp] = tt;
		 }
		 tmp /= 2;
	 }
	 ls[0] = s;
}

完整的參數請參考我的鏈接:https://github.com/clarkzhang56/the-method-of-sort/blob/master/externalsorting/externalsort.c點擊打開鏈接

       如此,循環操作直到所有的數據排序完。


 

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