//利用败者树求:
//20个一维数组,每个数组有500个元素,为叶子节点提供数据。本题中仅给出了测试用的
//40个元素,例程中输出最大的前10个元素
#include<iostream>
#include<vector>
using namespace std;
const int branchesLength=20; //共有20路数组
int branches[branchesLength][500]=
{
{1000,90},{999,888},{1001,990},{887,877},{987,978},
{1001,901},{992,883},{1005,992},{887,877},{987,978},
{1002,902},{993,884},{1007,991},{887,877},{987,978},
{1003,903},{994,882},{989,900},{887,877},{987,978}
};
//败者树的非叶子节点,记录数据源的索引位置,根据节点的值可以定位到所指向的数据源
int tree[branchesLength];
//败者树的叶子节点,叶子节点与数据源是一一对应的,即第一个叶子节点记录第一个数据源的当前数据
//编号都是从0开始
int nodes[branchesLength];
//nodes_iterator[i]记录第i路数组当前已取到第几个元素(从0开始)
int nodes_iterator[branchesLength]={0};
//设置第index个叶子节点的下一个数据
void put(int index)
{
nodes[index]=branches[index][nodes_iterator[index]++];
}
//获取第index叶子节点的当前数据
int get(int index)
{
return nodes[index];
}
//调整第index个叶子节点,具体调整过程为:叶子节点和父节点比较,败者留着父节点的位置,
//胜者继续和父节点的父节点比较,直到树的根节点
//核心函数
void adjust(int index)
{
int size=branchesLength;
int t=(size+index)/2;
while(t>0)
{
if(get(tree[t])>get(index))
{
int temp=tree[t];
tree[t]=index;
index=temp;
}
t/=2;
}
tree[0]=index; //此轮胜者
}
//依次读取数据源中的数据进行归并排序,返回排序后的数据列表
vector<int> Merge()
{
vector<int> list1;
int top;
int i=0;
while(i<10)
{
top=nodes[tree[0]];
list1.push_back(top);
cout<<top<<" ";
i++;
put(tree[0]);
adjust(tree[0]);
}
return list1;
}
//初始化构建败者树
void init()
{
int size=branchesLength;
for(int i=0;i<size;i++)
put(i);
int winner=0;
for(int i=1;i<size;i++)
{
if(get(i)>get(winner))
winner=i;
}
for(int i=0;i<branchesLength;i++) //非叶子节点初始化为冠军节点
tree[i]=winner;
for(int i=size-1;i>=0;i--) //从后向前依次调整非叶子节点
adjust(i);
}
int main()
{
init();
Merge();
}
败者树
最新推荐文章于 2024-11-21 17:45:21 发布