本文是笔者2020年秋哈工大数据结构作业5自己的代码,由于本人能力有限,可能存在一些错误,欢迎指出。
本次作业是二选一,临近期末,笔者就选了个比较水的败者树。
作业题目:利用败者树实现锦标赛排序(树形选择排序)
败者树实际上是一棵完全二叉树,可以看作是胜者树的一种变体。败者树简化了重构,败者树的重构只是与该结点的父结点的记录有关,而胜者树的重构还与该结点的兄弟结点有关。败者树作为一种重要的数据结构,用于树形选择排序和外部排序。本作业要求设计败者树的存储结构,并实现树形选择排序算法。
设计败者树的存储结构
#define Maxsize 100
#define Infinity 1000
#define Min -1
typedef struct {
int key;
int id;
}STree;
利用败者树实现锦标赛排序
(1)败者树的初始化算法
//败者树初始化
int Initial(int n,int A[],STree ST[])
{
for (int i = n; i <= 2 * n - 1; i++)
{
ST[i].id = i;
ST[i].key = A[i - n + 1];
}
return 2 * n - 1;
}
(2)败者树的构建算法
//败者树的建立
int Build(STree ST[], int Treelast, int n)
{
int i = Treelast, father,temp,tempid;
int champ, champid;
//把树节点全部初始化为Min
for (int i = 1; i < n; i++)
ST[i].key = Min;
for (int i = Treelast; i >= n; i--)
{
father = i/2;
champ = ST[i].key;
champid = ST[i].id;
//与父结点比较,直到比较的胜者为无穷小
while (father >= 1 && champ != Min)
{
if (champ > ST[father].key)
{
temp = ST[father].key;
tempid = ST[father].id;
ST[father].key = champ;
ST[father].id = champid;
champ = temp;
champid = tempid;
}
father /= 2;
}
}
ST[0].id = champid;
ST[0].key = champ;
return champid;
}
(3)败者树的重构算法
//败者树的重构
int Rebuild(int minid, STree ST[], int Treelast)
{
int father = minid / 2, temp, tempid;
int champ = ST[minid].key, champid = ST[minid].id;
//一直与父节点比较
while (father >= 1)
{
if (champ > ST[father].key)
{
temp = ST[father].key;
tempid = ST[father].id;
ST[father].key = champ;
ST[father].id = champid;
champ = temp;
champid = tempid;
}
father /= 2;
}
ST[0].id = champid;
ST[0].key = champ;
return champid;
}
(4)锦标赛排序算法
//主函数
int main()
{
int n,TLast,minid;
int A[Maxsize];
ifstream in("data.txt");
in >> n;
for (int i = 1; i <= n; i++)
{
in >> A[i];
}
in.close();
STree ST[Maxsize];
TLast = Initial(n, A, ST);
minid = Build(ST, TLast, n);
A[1] = ST[minid].key;
ST[minid].key = Infinity;
for (int i = 2; i <= n; i++)
{
minid = Rebuild(minid, ST, TLast);
//选择最小值保存
A[i] = ST[minid].key;
ST[minid].key = Infinity;
}
for (int i = 1; i <= n; i++)
cout << A[i] << " ";
cout << endl;
return 0;
}