集美大学课程实验报告-实验4:二叉树与查找
| 项目名称 | 内容 |
|---|---|
| 课程名称 | 数据结构 |
| 班级 | 网安2511 |
| 实验项目名称 | 二叉树与查找 |
| 上机实践日期 | 2026. 4.16和2026.4.30 |
| 上机实践时间 | 4 学时 |
一、目的(本次实验所涉及并要求掌握的知识点)
以下内容请根据实际情况编写
- 掌握创建二叉树与树及二叉树上的基本操作
- 熟练掌握树的递归结构及在其上的递归算法
- 掌握二叉树的层次遍历
- 掌握BST树上的搜索、创建与删除
- 掌握哈希表、平衡树的应用
二、实验内容与设计思想
以下请根据实际情况编写
题目1:先序序列创建二叉树
函数1CreateNode相关伪代码
函数 CreateNode(v)
申请新结点node
node的data = v
node的左孩子 = NULL
node的右孩子 = NULL
返回 node
函数代码
BiTNode* CreateNode(char v) {
BiTNode* node = new BiTNode;
node->data = v;
node->lchild = NULL;
node->rchild = NULL;
return node;
}
时间复杂度:
O(1)
空间复杂度:
O(1)
函数2CreateTreeByPreOrder相关伪代码
函数 CreateTreeByPreOrder(str)
if 索引越界 then
返回 NULL
ch = str[当前索引]
索引后移一位
if ch == '#' then
返回 NULL
root = CreateNode(ch)
root的左孩子 = CreateTreeByPreOrder(str)
root的右孩子 = CreateTreeByPreOrder(str)
返回 root
函数代码
BiTree CreateTreeByPreOrder(string str) {
if (index >= str.length()) return NULL;
char ch = str[index++];
if (ch == '#') return NULL;
BiTree root = CreateNode(ch);
root->lchild = CreateTreeByPreOrder(str);
root->rchild = CreateTreeByPreOrder(str);
return root;
}
时间复杂度:
O(n)
空间复杂度:
O(n)
题目2:先序输出叶结点
函数PreorderPrintLeaves相关伪代码
函数 PreorderPrintLeaves(BT)
if BT == NULL then
return
if BT的左孩子 == NULL AND BT的右孩子 == NULL then
输出 " " + BT的Data
return
PreorderPrintLeaves(BT的左孩子)
PreorderPrintLeaves(BT的右孩子)
函数代码
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);
}
时间复杂度:
O(n)
空间复杂度:
O(n)
题目3:求二叉树高度
函数GetHeight相关伪代码
函数 GetHeight(BT)
if BT == NULL then
return 0
leftHeight = GetHeight(BT的左孩子)
rightHeight = GetHeight(BT的右孩子)
return max(leftHeight, rightHeight) + 1
函数代码
int GetHeight(BinTree BT) {
if (BT == NULL) return 0;
int leftHeight = GetHeight(BT->Left);
int rightHeight = GetHeight(BT->Right);
return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1;
}
时间复杂度:
O(n)
空间复杂度:
O(n)
题目4:二叉树层次遍历
函数1CreateTreeFromArray相关伪代码
函数 CreateTreeFromArray(arr, n, i)
if i >= n 或 arr[i] == '#' then
return NULL
BT = 申请新结点
BT的Data = arr[i]
BT的左孩子 = CreateTreeFromArray(arr, n, 2 * i)
BT的右孩子 = CreateTreeFromArray(arr, n, 2 * i + 1)
return BT
函数代码
BinTree CreateTreeFromArray(char arr[], int n, int i) {
if (i >= n || arr[i] == '#') return NULL;
BinTree BT = (BinTree)malloc(sizeof(struct TNode));
BT->Data = arr[i];
BT->Left = CreateTreeFromArray(arr, n, 2 * i);
BT->Right = CreateTreeFromArray(arr, n, 2 * i + 1);
return BT;
}
时间复杂度:
O(n)
空间复杂度:
O(n)
函数2LevelOrderTraverse相关伪代码
函数 LevelOrderTraverse(BT)
if BT == NULL then
输出 "NULL"
return
创建空队列Q
将BT入队
while 队列不为空 do
node = 队列出队
输出 node的Data
if node的左孩子 != NULL then
将左孩子入队
if node的右孩子 != NULL then
将右孩子入队
if 队列不为空 then
输出 " "
end while
函数代码
void LevelOrderTraverse(BinTree BT) {
if (BT == NULL) {
printf("NULL");
return;
}
BinTree queue[1000];
int front = 0, rear = 0;
queue[rear++] = BT;
while (front < rear) {
BinTree node = queue[front++];
printf("%c", node->Data);
if (node->Left != NULL) queue[rear++] = node->Left;
if (node->Right != NULL) queue[rear++] = node->Right;
if (front < rear) printf(" ");
}
}
时间复杂度:
O(n)
空间复杂度:
O(w)
题目5:创建二叉排序树并遍历
函数1InsertBST相关伪代码
函数 InsertBST(root, val)
if root == NULL then
创建新结点
root的data = val
return root
if val < root的data then
root的左孩子 = InsertBST(root的左孩子, val)
else if val > root的data then
root的右孩子 = InsertBST(root的右孩子, val)
return root
函数代码
BSTNode* InsertBST(BSTNode* root, int val) {
if (root == NULL) {
BSTNode* newNode = (BSTNode*)malloc(sizeof(BSTNode));
newNode->data = val;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
if (val < root->data) {
root->left = InsertBST(root->left, val);
} else if (val > root->data) {
root->right = InsertBST(root->right, val);
}
return root;
}
时间复杂度:
O(log n)
空间复杂度:
O(h)
函数2InOrderTraverse相关伪代码
函数 InOrderTraverse(root)
if root != NULL then
InOrderTraverse(root的左孩子)
输出 root的data
InOrderTraverse(root的右孩子)
函数代码
void InOrderTraverse(BSTNode* root) {
if (root == NULL) return;
InOrderTraverse(root->left);
printf("%d ", root->data);
InOrderTraverse(root->right);
}
时间复杂度:
O(n)
空间复杂度:
O(h)
题目6:BST的查找、插入与删除
函数DeleteBST相关伪代码
函数 DeleteBST(root, val)
if root == NULL then
return NULL
if val < root的data then
root的左孩子 = DeleteBST(root的左孩子, val)
else if val > root的data then
root的右孩子 = DeleteBST(root的右孩子, val)
else
if root的左孩子 == NULL then
temp = root的右孩子
free(root)
return temp
else if root的右孩子 == NULL then
temp = root的左孩子
free(root)
return temp
else
minNode = FindMin(root的右孩子)
root的data = minNode的data
root的右孩子 = DeleteBST(root的右孩子, minNode的data)
end if
end if
return root
函数代码
BSTNode* DeleteBST(BSTNode* root, int val) {
if (root == NULL) return NULL;
if (val < root->data) {
root->left = DeleteBST(root->left, val);
} else if (val > root->data) {
root->right = DeleteBST(root->right, val);
} else {
if (root->left == NULL) {
BSTNode* temp = root->right;
free(root);
return temp;
} else if (root->right == NULL) {
BSTNode* temp = root->left;
free(root);
return temp;
} else {
BSTNode* minNode = FindMin(root->right);
root->data = minNode->data;
root->right = DeleteBST(root->right, minNode->data);
}
}
return root;
}
时间复杂度:
O(h)
空间复杂度:
O(h)
题目7:航空公司VIP客户查询
函数1hash相关伪代码
函数 hash(s)
h = 0
for i = 0 to s的长度-1 do
h = (h * 131 + s[i]) mod HASH_SIZE
end for
return h
函数代码
int hash(char* s) {
unsigned int h = 0;
for (int i = 0; s[i]; i++) {
h = h * 131 + s[i];
}
return h % HASH_SIZE;
}
时间复杂度:
O(1)
空间复杂度:
O(1)
函数2insert相关伪代码
函数 insert(id, miles, K)
index = hash(id)
addMiles = (miles < K) ? K : miles
p = hashTable[index]
while p != NULL do
if strcmp(p的id, id) == 0 then
p的miles = p的miles + addMiles
return
end if
p = p的next
end while
newNode = 创建新结点
newNode的id = id
newNode的miles = addMiles
newNode的next = hashTable[index]
hashTable[index] = newNode
函数代码
void insert(char* id, int miles, int K) {
int h = hash(id);
int addMiles = (miles < K) ? K : miles;
Node* p = hashTable[h];
while (p) {
if (strcmp(p->id, id) == 0) {
p->miles += addMiles;
return;
}
p = p->next;
}
Node* newNode = (Node*)malloc(sizeof(Node));
strcpy(newNode->id, id);
newNode->miles = addMiles;
newNode->next = hashTable[h];
hashTable[h] = newNode;
}
时间复杂度:
O(1)
空间复杂度:
O(1)
函数3find相关伪代码
函数 find(id)
index = hash(id)
p = hashTable[index]
while p != NULL do
if strcmp(p的id, id) == 0 then
return p的miles
end if
p = p的next
end while
return -1
函数代码
int find(char* id) {
int h = hash(id);
Node* p = hashTable[h];
while (p) {
if (strcmp(p->id, id) == 0) {
return p->miles;
}
p = p->next;
}
return -1;
}
时间复杂度:
O(1)
空间复杂度:
O(1)
三、实验使用环境(本次实验所使用的平台和相关软件)
以下请根据实际情况编写
- 操作系统:Windows 11
- 编程语言:C++
- 开发工具:Visual Studio 2026
- 编译器:Microsoft Visual C++
四、实验步骤和调试过程(实验步骤、测试数据设计、测试结果分析)
以下请根据实际情况编写
题目1:先序序列创建二叉树
本机运行截图

PTA提交截图

题目2:先序输出叶结点
本机运行截图

PTA提交截图

题目3:求二叉树的高度
本机运行截图

PTA提交截图

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

PTA提交截图

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

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



题目7:航空公司VIP客户查询
本机运行截图

PTA提交截图

五、实验小结(实验中遇到的问题及解决过程、实验体会和收获)
以下请根据实际情况编写
遇到的问题及解决方法:
- 问题:递归创建二叉树时栈溢出。
- 解决方法:递归终止条件未正确设置,确保遇到#时正确返回NULL
- 问题:层次遍历输出格式错误。
- 解决方法:结点间空格处理不当,使用 if (front < rear) printf(" ") 控制最后一个结点后无空格。
- 问题:BST删除结点逻辑错误。
- 解决方法:找到右子树最小值替换后,递归删除右子树中的那个最小值
实验体会和收获:
- 掌握了中序遍历BST得到有序序列的特性。
- 理解了二叉树递归创建和遍历的本质。
六、附件(参考文献和相关资料)
无
浙公网安备 33010602011771号