1、问题定义
)从team.txt中读取参赛队伍的基本信息,实现基于二叉排序树的查找。根据提示输入参赛队编号,若查找成功,输出该赛事类别对应的基本信息(参赛作品名称、参赛学校、赛事类别、参赛者和指导老师信息),同时,输出查找成功时的平均查找长度ASL;否则,输出“查找失败!”。
2、问题分析
首先问题一我们要考虑怎么将给定的信息(参赛作品名称、参赛学校、赛事类别、参赛者、指导老师和参赛编号)插入到二叉排序树中。
这边可以使用了指针引用,以便能够在函数内部修改指针p所指向的节点,并将新节点插入到对应的位置。
首先,该函数判断当前节点p是否为NULL,如果是,则创建一个新节点,并将所有信息赋值给该新节点。否则,如果给定的参赛编号code小于节点p的参赛编号,则在其左子树中继续查找相应的位置;如果大于等于节点p的参赛编号,则在其右子树中继续查找相应的位置。
由此,它实现了二叉排序树中加入新节点的逻辑,总的来说就是保证在有序的基础上进行数据存储和访问。以下是代码展示
void insert(trnode*& p, string name, string school, string category, string participant, string teacher, int code)
{
if (p == NULL) {
p = new trnode;
p->name = name;
p->school = school;
p->category = category;
p->participant = participant;
p->teacher = teacher;
p->code = code;
p->left = NULL;
p->right = NULL;
}
else if (code < p->code) {
insert(p->left, name, school, category, participant, teacher, code);
}
else {
insert(p->right, name, school, category, participant, teacher, code);
}
}
其次怎么计算ASL,代码如下:
trnode* find(trnode* p, int code, int& count)
{
if (p == NULL) {
return NULL;
}
else if (code == p->code) {
count++;
return p;
}
else if (code < p->code) {
count++;
return find(p->left, code, count);
}
else {
count++;
return find(p->right, code, count);
}
}
分析:函数首先会检查当前查找的子树是否为空,如果为空则证明没有找到对应节点,直接返回NULL。如果不是空节点,则根据代码和该节点存储的代码进行比较。如果它们相等,则证明找到了对应节点并将count+1
;否则如果要查找的代码小于节点所存储的代码,则往左子树递归查找,并将count+1
;如果要查找的代码大于节点所存储的代码,则往右子树递归查找,并将count+1
。最终结果是函数返回被找到节点的地址(如果存在),并且计数器count
记录了查找成功时的平均查找长度ASL.
最后我们要在主函数中从文件读入数据并将数据插入二叉排序树中的程序。
完整实现代码如下:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct trnode {
string name;
string school;
string category;
string participant;
string teacher;
int code;
trnode* left;
trnode* right;
};
void insert(trnode*& p, string name, string school, string category, string participant, string teacher, int code)
{
if (p == NULL) {
p = new trnode;
p->name = name;
p->school = school;
p->category = category;
p->participant = participant;
p->teacher = teacher;
p->code = code;
p->left = NULL;
p->right = NULL;
}
else if (code < p->code) {
insert(p->left, name, school, category, participant, teacher, code);
}
else {
insert(p->right, name, school, category, participant, teacher, code);
}
}
trnode* find(trnode* p, int code, int& count)
{
if (p == NULL) {
return NULL;
}
else if (code == p->code) {
count++;
return p;
}
else if (code < p->code) {
count++;
return find(p->left, code, count);
}
else {
count++;
return find(p->right, code, count);
}
}
int main()
{
trnode* root = NULL;
ifstream fin("C:\\Users\\韦诗园\\Desktop\\team.txt");
if (!fin.is_open()) {
cout << "Failed to open file." << endl;
return 0;
}
string line;
while (getline(fin, line)) {
int code = stoi(line.substr(0, line.find('#')));
line.erase(0, line.find('#') + 1);
string name = line.substr(0, line.find('#'));
line.erase(0, line.find('#') + 1);
string school = line.substr(0, line.find('#'));
line.erase(0, line.find('#') + 1);
string category = line.substr(0, line.find('#'));
line.erase(0, line.find('#') + 1);
string participant = line.substr(0, line.find('#'));
line.erase(0, line.find('#') + 1);
string teacher = line.substr(0, line.find('#'));
insert(root, name, school, category, participant, teacher, code);
}
fin.close();
int search_num;
cout << "请输入查询的参赛编号:";
cin >> search_num;
int count = 0;
trnode* result = find(root, search_num, count);
if (result == NULL) {
cout << "未找到查询结果。" << endl;
}
else {
cout << "查询结果如下:" << endl;
cout << "参赛作品名称:" << result->name << endl;
cout << "参赛学校:" << result->school << endl;
cout << "赛事类别:" << result->category << endl;
cout << "参赛者:" << result->participant << endl;
cout << "指导老师:" << result->teacher << endl;
double asl = (double)count / 5.0; // 这里假设查询信息需要比较5次
cout << "ASL为:" << asl << endl;
}
return 0;
}
3、出现的问题
实验过程中可能会出现错误提醒,但是最终运行的结果是对的,可以参考,还需改进。