利用败者树进行外部排序时,要根据叶节点构造败者树。仔细理解了这个构造的过程。
I.
一个直接的思路就是类似我们手工构造一个败者树的过程。开始初始化所有败者树的节点值为-1。依次填含有叶节点的节点。A包含叶节点,比较A的左右孩子节点(左孩子可能不是叶节点,右孩子是叶节点),败者填入A。胜者与A的父节点B比较,如果B没有填值,则胜者填入B;如果B已经填值,用胜者值与B的值比较,败者值填入B,然后又获得新的胜者值。再用新的胜者值与B的父节点C比较。重复类似的比较直至胜者值被填入某个节点中。
一个问题:填完所有的子节点含有叶节点的节点后,败者树就初始化完?一个不严格的理解是:虽然败者树的节点数只是numLeaves,没有包含叶节点,我们可以假想这个树包含叶节点,并且值都是-1。填完后所有子节点包含叶节点的节点后,意味着所有叶节点都已经插入到败者树中,则败者树初始化完成。
/*
初始化一个败者树,胜者是Key值小的元素。
numLeaves:叶节点个数
KeyT leaves[numLeaves+1]:节点数组下标从1开始,保存每个叶节点的Key值
intloserTree[numLeaves]:只存储每个叶节点在数组leaves中的下标。loserTree[0]存储冠军,所以节点数组下标1开始。
*/
template <class KeyT>
void InitTree(KeyT * leaves,intnumLeaves,int *loserTree){
for(int i=0;i<numLeaves;i++){ //初始化每个树的节点值