一、实验目的
(1)掌握树的逻辑结构
(2)理解树的孩子兄弟存储结构
(3)掌握二叉树的逻辑结构
(4)掌握二叉树的二叉链表存储结构
(5)掌握基于二叉链表存储的二叉树的遍历操作的实现
(6)掌握二叉树遍历的应用
二、实验环境(实验设备)
硬件: 微型计算机P4
软件: Windows 7 + Microsoft Visual Studio2019
三、实验内容(包括题目和要求、源码、运行结果截图等)
题目1. 满二叉树判断
实验要求:
- 实现一个模板函数IsFullTree判断一棵二叉树是否是满二叉树;
- 利用编程模板中提供的主函数,测试算法正确性。
源码:
#pragma once
template <class ElemType>
bool IsFullTree(const BinaryTree<ElemType>& bt)
// 操作结果: 判断二叉树bt是否是满二叉树
{
int NodeCount = bt.NodeCount();
int height = bt.Height();
if (NodeCount == pow(2, height) - 1) {
return 1;
}
return 0;
}
运行结果截图:
题目3:相似二叉树判断
实验要求:
- 实现一个模板函数IsSimilarHelp判断以r1和r2为根的两棵二叉树是否相似;
- 利用编程模板中提供的主函数,测试插入和删除函数的正确性。
源码:
#pragma once
template <class ElemType>
bool IsSimilarHelp(const BinTreeNode<ElemType>* r1, const BinTreeNode<ElemType>* r2)
// 操作结果: 判断以r1和r2为根的两棵二叉树是否相似
{
if (r1 == NULL && r2 == NULL) return true;
else if (r1 == NULL || r2 == NULL)return false;
else return IsSimilarHelp(r1->leftChild, r2->leftChild) && IsSimilarHelp(r1->rightChild, r2->rightChild);
}
template <class ElemType>
bool IsSimilar(const BinaryTree<ElemType>& bt1, const BinaryTree<ElemType>& bt2)
// 操作结果: 判断两棵二叉树是否相似
{
return IsSimilarHelp(bt1.GetRoot(), bt2.GetRoot());
}
运行结果截图:
题目4.:二叉树结点交换
实验要求:
- 实现一个模板函数SwapBiTreeHelp交换以r为根的二叉树的所有结点的左右孩子
- 利用编程模板中提供的主函数中测试算法正确性。
源码:
template <class ElemType>
void SwapBiTreeHelp(BinTreeNode<ElemType>* r)
// 操作结果: 交换以r为根的二叉树的所有结点的左右孩子
{
BinTreeNode<ElemType>* temp = r->leftChild;
r->leftChild = r->rightChild;
r->rightChild = temp;
if (r->rightChild != NULL)SwapBiTreeHelp((BinTreeNode<ElemType> *)r->rightChild);
if (r->leftChild != NULL)SwapBiTreeHelp((BinTreeNode<ElemType>*)r->leftChild);
}
template <class ElemType>
void SwapBiTree(BinaryTree<ElemType>& bt)
// 操作结果: 交换二叉树的所有结点的左右孩子
{
SwapBiTreeHelp((BinTreeNode<ElemType> *)bt.GetRoot()); // 调用辅助函数实现交换二叉树的所有结点的左右孩子
}
#pragma once
运行结果截图:
题目5. 统计叶结点个数
实验要求:
(1)实现一个模板函数LeafNodeCountHelp统计以r为根的二叉树的叶结点个数。
(2)利用编程模板中提供的主函数,测试算法正确性。
源码:
template <class ElemType>
int LeafNodeCountHelp(const BinTreeNode<ElemType>* r)
// 操作结果: 统计以r为根的二叉树的叶结点个数
{
if (r == NULL)return 0;
if (r->leftChild == NULL & r->rightChild == NULL)return 1;
return LeafNodeCountHelp(r->leftChild) + LeafNodeCountHelp(r->rightChild);
}
template <class ElemType>
int LeafNodeCount(BinaryTree<ElemType> bt)
// 操作结果: 统计二叉树的叶结点个数
{
return LeafNodeCountHelp(bt.GetRoot()); // 调用辅助函数统计二叉树的叶结点个数
}
运行结果截图:
题目6. 构造二叉树
实验要求:
(1)实现一个模板函数CreateBinaryTreeHelp_PostIn,该函数通过二叉树的后序序列post[postLeft..postRight]和中序序列in[inLeft..inRight]构造以r为根的二叉树
(2)利用编程模板中提供的主函数,测试算法正确性。
源码:
template <class ElemType>
void CreateBinaryTreeHelp_PostIn(BinTreeNode<ElemType>*& r, ElemType post[], ElemType in[],
int postLeft, int postRight, int inLeft, int inRight)
// 操作结果:已知二叉树的后序序列post[postLeft..postRight]和中序序列in[inLeft..inRight]构造
// 以r为根的二叉树
{
if (postRight < postLeft || inRight < inLeft) {
return;
}
int i;
for (i = inLeft; i <= inRight; i++) {
if (in[i] == post[postRight]) {
break;
}
}
r = new BinTreeNode<ElemType>(in[i]);
CreateBinaryTreeHelp_PostIn<ElemType>(r->leftChild, post, in, postLeft, postLeft + i - inLeft - 1, inLeft, i - 1);
CreateBinaryTreeHelp_PostIn<ElemType>(r->rightChild, post, in, postLeft + i - inLeft, postRight - 1, i + 1, inRight);
}
template <class ElemType>
BinaryTree<ElemType> CreateBinaryTree_PostIn(ElemType post[], ElemType in[], int n)
// 操作结果:已知后序和中序序列构造二叉树
{
BinTreeNode<ElemType>* r; // 二叉树的根
CreateBinaryTreeHelp_PostIn<ElemType>(r, post, in, 0, n - 1, 0, n - 1);
return BinaryTree<ElemType>(r); // 返回以r为根的二叉树
}
运行结果截图:
四、实验小结(包括实验过程中遇到问题和解决方法、心得体会等)
1.树型结构的设计可以帮助我们更清晰地理解和组织复杂的数据结构。
2.在创建和操作树型结构时,需要细心和耐心,否则会导致树的结构混乱或错误。
3.树型结构的遍历算法是重要的,因为它可以帮助我们有效地访问和操作树中的节点。
4.在实际应用中使用树型结构时,我们需要权衡组织数据的方式和查找/访问速度之间的平衡。
5.学习树型结构的编程实践可以增强我们的编程知识和技能,并且在解决实际问题时可以发挥巨大的作用。
6. 学习理论知识很重要,但实践更能深入理解。通过对树的构建、插入、删除、查找等算法的实践,可以更清楚地了解树的结构和算法实现的细节。