集美大学课程实验报告-实验4-树、二叉树与查找
集美大学课程实验报告-实验4-树、二叉树与查找
| 项目名称 | 内容 |
|---|---|
| 课程名称 | 数据结构 |
| 班级 | 网安2511 |
| 学号 | 202521336001 |
| 实验项目名称 | 树、二叉树与查找 |
| 上机实践日期 | 2026.05.09 |
| 上机实践时间 | 2学时 |
一、目的(本次实验所涉及并要求掌握的知识点)
- 掌握二叉树与树及二叉树的基本操作。
- 掌握二叉树的层次遍历。
- 掌握BST树上的搜索、创建与删除。
- 掌握哈希表、平衡树的应用。
二、实验内容与设计思想
题目1:先序序列创建二叉树
函数相关伪代码
BuildTree(s, index):
如果 index 超出字符串长度 或 s[index] == '#':
index 加 1
返回空指针
创建新节点 root
root.data ← s[index]
index 加 1
root.lchild ← BuildTree(s, index)
root.rchild ← BuildTree(s, index)
返回 root
InOrderTraversal(root):
如果 root 不为空:
InOrderTraversal(root.lchild)
输出 root.data
InOrderTraversal(root.rchild)
FreeTree(root):
如果 root 不为空:
FreeTree(root.lchild)
FreeTree(root.rchild)
删除 root
主程序:
读入字符串 s
初始化 index ← 0
root ← BuildTree(s, index)
调用 InOrderTraversal(root)
调用 FreeTree(root)
函数代码
#include <iostream>
#include <string>
using namespace std;
typedef char ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
BiTree BuildTree(string& s, int& index) {
if (index >= s.size() || s[index] == '#') {
index++;
return nullptr;
}
BiTree root = new BiTNode;
root->data = s[index];
index++;
root->lchild = BuildTree(s, index);
root->rchild = BuildTree(s, index);
return root;
}
//中序
void InOrderTraversal(BiTree root) {
if (root != NULL) {
InOrderTraversal(root->lchild);
cout << root->data << " ";
InOrderTraversal(root->rchild);
}
}
void FreeTree(BiTree root) {
if (root != NULL) {
FreeTree(root->lchild);
FreeTree(root->rchild);
delete root;
}
}
int main() {
string s;
while (cin >> s) {
int index = 0;
BiTree root = BuildTree(s, index);
InOrderTraversal(root);
cout << endl;
FreeTree(root);
}
return 0;
}
题目2:先序输出叶结点
函数相关伪代码
PreorderPrintLeaves(BT):
如果 BT 为空:
返回
如果 BT 是叶结点:
输出 " " + BT.Data
PreorderPrintLeaves(BT.Left)
PreorderPrintLeaves(BT.Right)
函数代码
void PreorderPrintLeaves( BinTree BT ) {
if (BT == NULL) {
return;
}
if (BT->Left == NULL && BT->Right == NULL) {
printf(" %c", BT->Data);
return;
}
PreorderPrintLeaves(BT->Left);
PreorderPrintLeaves(BT->Right);
}
题目3:求二叉树高度
函数相关伪代码
FUNCTION GetHeight(BT):
IF BT IS NULL THEN
RETURN 0
END IF
left_height = GetHeight(BT.Left)
right_height = GetHeight(BT.Right)
IF left_height > right_height THEN
RETURN left_height + 1
ELSE
RETURN right_height + 1
END IF
END FUNCTION
函数代码
int GetHeight( BinTree BT ) {
if (BT == NULL) {
return 0;
}
int leftHeight = GetHeight(BT->Left);
int rightHeight = GetHeight(BT->Right);
if (leftHeight > rightHeight) {
return leftHeight + 1;
} else {
return rightHeight + 1;
}
}
题目4:二叉树层次遍历
函数相关伪代码
BuildTree(index):
if index > n 或 s[index] == '#':
return NULL
node = new TreeNode(s[index])
node.left = BuildTree(2 * index)
node.right = BuildTree(2 * index + 1)
return node
LevelOrder(root):
if root == NULL:
print "NULL"
return
queue ← root
first ← true
while queue 非空:
node ← queue.pop()
if first:
print node.data
first ← false
else:
print " " + node.data
if node.left != NULL:
queue.push(node.left)
if node.right != NULL:
queue.push(node.right)
函数代码
#include <iostream>
#include <queue>
#include <string>
using namespace std;
struct TreeNode {
char data;
TreeNode* left;
TreeNode* right;
TreeNode(char d) : data(d), left(NULL), right(NULL) {}
};
string s;
// 根据顺序存储构建二叉链表
TreeNode* buildTree(int index) {
if (index >= s.length() || s[index] == '#')
return NULL;
TreeNode* node = new TreeNode(s[index]);
node->left = buildTree(2 * index);
node->right = buildTree(2 * index + 1);
return node;
}
// 层次遍历
void levelOrder(TreeNode* root) {
if (!root) {
cout << "NULL";
return;
}
queue<TreeNode*> q;
q.push(root);
bool first = true;
while (!q.empty()) {
TreeNode* cur = q.front();
q.pop();
if (first) {
cout << cur->data;
first = false;
} else {
cout << " " << cur->data;
}
if (cur->left) q.push(cur->left);
if (cur->right) q.push(cur->right);
}
}
int main() {
cin >> s;
TreeNode* root = buildTree(1); // 从下标1开始
levelOrder(root);
return 0;
}
题目5:创建二叉排序树并遍历
函数相关伪代码
定义节点:存数字,左、右指针
函数 add(树, x):
空就新建节点
小就放左边
大放右边
函数 in(树):
左 → 输出 → 右
主函数:
读数字,加入树
中序遍历输出
函数代码
#include <iostream>
using namespace std;
struct Node {
int data;
Node *l, *r;
};
void add(Node* &t, int x) {
if(!t) {
t=new Node;
t->data=x;
t->l=t->r=NULL;
} else if(x<t->data) add(t->l,x);
else add(t->r,x);
}
void in(Node* t) {
if(t) {
in(t->l);
cout<<t->data<<" ";
in(t->r);
}
}
int main() {
Node* root=NULL;
int x;
while(cin>>x) add(root,x);
in(root);
return 0;
}
题目6:BST的查找与插入
函数相关伪代码
定义节点结构
数据 data
左孩子 left
右孩子 right
函数 查找(根, 关键字)
如果 根为空 或 找到关键字
返回 根
如果 关键字 < 根数据
返回 查找左子树
否则
返回 查找右子树
函数 插入(根, 新数据)
如果 根为空
新建节点并赋值
如果 新数据 < 根数据
插入到左子树
如果 新数据 > 根数据
插入到右子树
函数代码
#include <iostream>
using namespace std;
struct Node {
int data;
Node *left, *right;
};
Node* search(Node* root, int key) {
if (!root || root->data == key)
return root;
if (key < root->data)
return search(root->left, key);
else
return search(root->right, key);
}
void insert(Node* &root, int key) {
if (!root) {
root = new Node;
root->data = key;
root->left = root->right = NULL;
return;
}
if (key < root->data) {
insert(root->left, key);
} else if (key > root->data) {
insert(root->right, key);
}
}
int main() {
Node* root = NULL;
int a[] = {50, 30, 80, 20, 40, 90, 10, 25, 35, 85, 23, 88};
int n = sizeof(a) / sizeof(a[0]);
for (int i = 0; i < n; i++) {
insert(root, a[i]);
}
int key;
cout << "请输入要查找的数字:";
cin >> key;
if (search(root, key))
cout << "找到 " << key << endl;
else
cout << "未找到 " << key << endl;
return 0;
}
题目7:哈希表、平衡树的应用
函数相关伪代码
定义结构体 VIP:
编号 id
姓名 name
创建哈希表数组 h,大小 N
创建标记数组 used,标记位置是否被占用
函数 哈希函数(s):
把字符串每个字符加起来 → 对 N 取模 → 返回下标
函数 插入(id, name):
计算位置 p
当位置 p 已被占用:
p = (p+1) % N
存入 id 和 name
标记 used[p] = 已占用
函数 查询(id):
计算位置 p
当位置 p 已被占用:
如果 h[p].id == 输入id
输出姓名,返回
p = (p+1) % N
输出 无此客户
主函数:
初始化 used 全部为 未占用
循环输入操作:
1 → 插入 id 和 name
2 → 查询 id
0 → 退出
函数代码
#include <iostream>
using namespace std;
const int N = 20;
struct VIP {
string id, name;
} h[N];
bool used[N];
int getHash(string s) {
int x = 0;
for(char c : s) x += c;
return x % N;
}
void insert(string id, string name) {
int p = getHash(id);
// 用 !used[p] 表示未被占用
while(used[p]) p = (p+1) % N;
h[p].id = id;
h[p].name = name;
used[p] = true;
}
void find(string id) {
int p = getHash(id);
while(used[p]) {
if(h[p].id == id) {
cout << "找到:" << h[p].name << endl;
return;
}
p = (p+1) % N;
}
cout << "无此客户" << endl;
}
int main() {
for(int i=0; i<N; i++) used[i] = false;
int op;
string id, name;
while(cin >> op) {
if(op == 1) {
cin >> id >> name;
insert(id, name);
}
else if(op == 2) {
cin >> id;
find(id);
}
else break;
}
return 0;
}
三、实验使用环境(本次实验所使用的平台和相关软件)
- 操作系统:Microsoft Windows [版本 10.0.26200.8246]
- 编程语言:C++
- 开发工具:Visual Studio 2022
- 编译器:VS2022
四、实验步骤和调试过程(实验步骤、测试数据设计、测试结果分析)
题目1:先序序列创建二叉树
本机运行截图

PTA提交截图

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

题目3:求二叉树高度
PTA提交截图

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

PTA提交截图

题目5:创建二叉排序树并遍历
本机运行截图

题目6:BST的查找与插入
本机运行截图

题目7:哈希表、平衡树的应用
本机运行截图
![image]()
五、实验小结(实验中遇到的问题及解决过程、实验体会和收获)
遇到的问题及解决方法:
- 问题:程序崩溃找不到原因
- 解决方法:使用打断点进行调试的方法。
- 问题:层次遍历队列空指针访问。
- 解决方法:入队前判断结点是否为空。
实验体会和收获:
- 掌握了二叉树的递归创建、遍历。
- 掌握队列实现层次遍历的方法。
- 理解哈希表O(1)平均查找效率。

浙公网安备 33010602011771号