实验报告:实验4-树、二叉树与查找
集美大学课程实验报告-实验4:树、二叉树与查找
| 项目名称 | 内容 |
|---|---|
| 课程名称 | 数据结构 |
| 班级 | 网安2512 |
| 学号 | 202521336053 |
| 实验项目名称 | 树、二叉树与查找 |
| 上机实践日期 | 2026年5月12日 |
| 上机实践时间 | 2学时 |
一、目的
- 掌握创建树的代码
- 熟悉如何创建二叉排序树以及遍历二叉树的方法
- 掌握如何查找二叉树
二、实验内容与设计思想
题目1:先序序列创建二叉树(编程题)
函数相关伪代码
算法:先序序列创建二叉树
输入:一段先序序列
输出:一个二叉排序树,和一个中序序列
1.输入一段先序序列
2.按照先序序列创建一个二叉排序树
3.依据二叉排序树输出一段中序序列
4.结束
函数代码
#include<iostream>
#include<string>
using namespace std;
struct Node{
char data;
Node* lchild;
Node* rchild;
Node(char d){
data=d;
lchild=NULL;
rchild=NULL;
}
};
Node* buildTree(const string& s,int& index)
{
if(index>=s.length())return NULL;
char ch=s[index++];
if(ch=='#')return NULL;
Node* node=new Node(ch);
node->lchild=buildTree(s,index);
node->rchild=buildTree(s,index);
return node;
}
void inorder(Node* root)
{
if(root==NULL)return ;
inorder(root->lchild);
cout<<root->data<<" ";
inorder(root->rchild);
}
void deleteTree(Node* root)
{
if(root==NULL)return ;
deleteTree(root->lchild);
deleteTree(root->rchild);
delete root;
}
int main()
{
string s;
while(cin>>s)
{
int index=0;
Node* root=buildTree(s,index);
inorder(root);
cout<<endl;
deleteTree(root);
}
return 0;
}
题目2:先序输出叶结点(函数题)
函数相关伪代码
算法:先序输出叶节点
输入:二叉排序树
输出:叶节点
1.输入一个二叉树的根节点
2.若为空树则输出NULL
3.若不为空树,先序找到没有左右孩子的结点
4.输出该结点的值并返回
5.结束
函数代码
void PreorderPrintLeaves(BinTree BT)
{
if(BT==NULL)return ;
if(BT->Left==NULL&&BT->Right==NULL)
{
printf(" %c",BT->Data);
}else
{
PreorderPrintLeaves(BT->Left);
PreorderPrintLeaves(BT->Right);
}
}
题目3:求二叉树高度(函数题)
函数相关伪代码
算法:递归函数
输入:输入一个二叉树的根结点
输出:二叉树的高度
1.输入一个二叉树的根结点
2.若为空树,则输出0
3.若不为空,则先遍历左子树,遇到叶节点后返回,再遍历右子树
4.比较左子树和右子树的最大高度,取出最大值,即为二叉树的高度
函数代码
int GetHeight(BinTree BT)
{
if(BT==NULL)return 0;
int Lefthight=GetHeight(BT->Left);
int Righthight=GetHeight(BT->Right);
return (Lefthight>Righthight?Lefthight:Righthight)+1;
}
题目4:二叉树层次遍历(编程题)
函数相关伪代码
算法:循环输出
输入:二叉树的顺序存储的字符
输出:二叉树的层次遍历顺序的字符
1.输入一段二叉树的顺序排序的字符
2.开始遍历,遇到'#'不输出,表示空结点,遇到字母才输出,直到所有字母输出完整
3.结束
函数代码
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s;
cin>>s;
int len=s.size();
bool hasNode=false;
for(int i=1;i<len;i++)
{
if(s[i]!='#')
{
hasNode=true;
break;
}
}
if(!hasNode)
{
cout<<"NULL"<<endl;
return 0;
}
bool first=true;
for(int i=1;i<len;i++)
{
if(s[i]!='#')
{
if(first)
{
cout<<s[i];
first=false;
}else
{
cout<<" "<<s[i];
}
}
}
cout<<endl;
return 0;
}
题目5、6:创建二叉树,并进行中序遍历,其中还有选择查找,插入,删除操作
函数相关伪代码
算法:二叉树的创建,遍历,插入,查找,删除
输入:一段数字
输出:完成二叉树的创建并中序遍历,后续可选择插入,查找和删除
1.输入一段数字
2.根据数字创建一个二叉排序树
3.进行中序遍历
4.接着可选择查找或者插入或者删除
5.结束
函数代码
#include<iostream>
using namespace std;
struct TreeNode {
int data;
TreeNode* left;
TreeNode* right;
TreeNode(int v):data(v),left(NULL),right(NULL){}
};
TreeNode* insert(TreeNode* root, int val)
{
if (!root)return new TreeNode(val);
if (val < root->data)root->left = insert(root->left, val);
if (val > root->data)root->right = insert(root->right, val);
return root;
}
void inorder(TreeNode* root)
{
if (root == nullptr)return;
inorder(root->left);
cout << root->data << " ";
inorder(root->right);
}
bool search(TreeNode* root, int val)
{
if (!root)return false;
if (val == root->data)return true;
else if (val < root->data)
return search(root->left, val);
else
return search(root->right, val);
}
TreeNode* findMin(TreeNode* root)
{
while (root && root->left)
root = root->left;
return root;
}
TreeNode* deleteNode(TreeNode* root, int val)
{
if (!root)return nullptr;
if (val < root->data)
{
root->left = deleteNode(root->left, val);
}
else if (val > root->data)
{
root->right = deleteNode(root->right, val);
}
else
{
if (root->left == nullptr)
{
TreeNode* rightChild = root->right;
delete root;
return rightChild;
}
else if (root->right == nullptr)
{
TreeNode* leftChild = root->left;
delete root;
return leftChild;
}
TreeNode* minNode = findMin(root->right);
root->data = minNode->data;
root->right = deleteNode(root->right, minNode->data);
}
return root;
}
void deleteTree(TreeNode* root)
{
if (!root)return;
deleteTree(root->left);
deleteTree(root->right);
delete root;
}
int main()
{
TreeNode* root = nullptr;
int x;
while (cin >> x )
{
root = insert(root, x);
}
cin.clear(); //清除failbit
cin.ignore(1024, '\n'); //忽略剩余字符(包括 '#' 和换行)
int choice, val;
cout << "二叉搜索树操作演示\n";
cout << "1. 插入\n2. 查找\n3. 删除\n4. 中序遍历\n5. 退出\n";
while (true) {
cout << "\n请选择操作: ";
cin >> choice;
switch (choice) {
case 1:
cout << "输入要插入的整数: ";
cin >> val;
root = insert(root, val);
cout << "插入完成\n";
break;
case 2:
cout << "输入要查找的整数: ";
cin >> val;
if (search(root, val))
cout << "找到了!\n";
else
cout << "未找到。\n";
break;
case 3:
cout << "输入要删除的整数: ";
cin >> val;
if (search(root, val)) {
root = deleteNode(root, val);
cout << "删除成功\n";
}
else {
cout << "值不存在,无法删除\n";
}
break;
case 4:
cout << "中序遍历结果: ";
inorder(root);
cout << endl;
break;
case 5:
deleteTree(root);
cout << "程序退出\n";
return 0;
default:
cout << "无效选项,请重新输入\n";
}
}
return 0;
}
题目7:QQ账号查询
函数相关伪代码
算法:哈希表与平衡树的应用
输入:一段数字
输出:创建一个QQ账号并给予查找和删除等操作
1.初始化数据结构
2.输入一段数字,创建一个QQ号
3.后续可进行查找,删除该QQ账号
4.结束
函数代码
#include<iostream>
#include<string>
#include<unordered_map>
#include<map>
using namespace std;
unordered_map<long long, string> hashMap;
map<long long, string> bstMap;
void insertAccount(long long qq, const string& name) {
hashMap[qq] = name;
bstMap[qq] = name;
cout << "插入成功!\n";
}
void searchAccount(long long qq) {
cout << "哈希表查找结果:";
auto it = hashMap.find(qq);
if (it != hashMap.end()) {
cout << "找到,昵称:" << it->second << endl;
}
else {
cout << "未找到该QQ号\n";
}
cout << "平衡树查找结果:";
auto it2 = bstMap.find(qq);
if (it2 != bstMap.end()) {
cout << "找到,昵称:" << it2->second << endl;
}
else {
cout << "未找到该QQ号\n";
}
}
void deleteAccount(long long qq) {
bool deleted = false;
if (hashMap.erase(qq)) deleted = true;
if (bstMap.erase(qq)) deleted = true;
if (deleted) cout << "删除成功!\n";
else cout << "账户不存在,删除失败\n";
}
void displayAll() {
if (bstMap.empty()) {
cout << "当前没有账户信息\n";
return;
}
cout << "所有账号(按QQ号升序):\n";
for (const auto& entry : bstMap) {
cout << "QQ号:" << entry.first << ",昵称:" << entry.second << endl;
}
}
int main() {
int choice;
long long qq;
string name;
cout << "=====QQ账户管理系统(演示哈希表与平衡树应用)=====\n";
while (true) {
cout << "\n请选择操作:\n";
cout << "1.插入账户\n";
cout << "2.查找账户\n";
cout << "3.删除账户\n";
cout << "4.显示所有账户(按QQ号排序)\n";
cout << "5.退出\n";
cout << "输入数字:";
cin >> choice;
switch (choice) {
case 1:
cout << "请输入QQ号(整数):";
cin >> qq;
cout << "请输入昵称:";
cin >> name;
insertAccount(qq, name);
break;
case 2:
cout << "请输入要查找的QQ号:";
cin >> qq;
searchAccount(qq);
break;
case 3:
cout << "请输入要删除的QQ号:";
cin >> qq;
deleteAccount(qq);
break;
case 4:
displayAll();
break;
case 5:
cout << "程序退出\n";
return 0;
default:
cout << "无效输入,请重新选择\n";
break;
}
}
}
三、实验使用环境
- 操作系统:Windows11 专业版
- 编程语言:C++
- 开发工具:visual studio
四、实验步骤和调试过程
题目1:先序序列创建二叉树(编程题)
本机运行截图

PTA提交截图

题目2:先序输出叶结点(函数题)
PTA提交截图

题目3:求二叉树高度(函数题)
PTA提交截图

题目4:二叉树层次遍历(编程题)
本机运行截图

PTA提交截图

题目5,6:二叉树的创建,遍历,查找和删除
本机运行截图

题目7:QQ账号查询

五、实验小结
遇到的问题及解决方法:
1.问题:二叉树的删除操作的代码有点难
- 解决方法:通过询问ai来分析该算法怎么执行并理解与应用
2.问题:哈希表与平衡树的应用不太熟悉 - 解决方法:通过看视频并询问ai来加以巩固
实验体会与收获:
- 学会了二叉排序树的创建、查找和删除
- 掌握了哈希表和平衡树的具体应用
六、附件
查询deepseek

浙公网安备 33010602011771号