您的位置:首页 > 其它

外部排序小结

2015-07-19 20:31 225 查看
相对于内部排序算法,外部排序算法是在数据量很大的情况下才有的。当数据量很大时,不能一次性将数据放入内存进行内部排序算法,只能将数据分块或者说分段,依次输入到内存中进行排序,然后将他们排序好的再排序,最后实现总的排序。

因此,外部排序用的方法就相对来说单一了——归并排序。在外部排序实现归并时,不仅归并排序耗时间,而且需要进行外存的读和写,而由计算机知识知道访问外存所需要的时间可是访问内存的至少十几倍。所以,提高外排的效率,就需要减少访问外存的次数,可以进行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点击打开链接

如此,循环操作直到所有的数据排序完。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: