二叉树的遍历
实验项目中文名称:二叉树的遍历
实验项目英文名称:Binary tree traverse
实验项目编码:3
实验学时:5
适用专业:信息与计算科学、数学与应用数学
所属课程:数据结构
开课学院:理学院
开课学期:第5学期
教材及实验指导书:
耿国华主编,《数据结构—(第三版)》,电子工业出版社,2011年
一、实验目的或任务
通过指导学生上机实践,对常用数据结构的基本概念及其不同的实现方法的理论得到进一步的掌握,并对在不同存储结构上实现不同的运算方式和技巧有所体会。
二、实验教学基本要求
1.了解实验目的及实验原理;
2.编写程序,并附上程序代码和结果图;
3.总结在编程过程中遇到的问题、解决办法和收获。
三、实验教学的内容或要求
1. 编写函数,输入字符序列,建立二叉树的二叉链表
//按照前序遍历建立二叉树(字符'#'为空树)
TreeNode* PreOrderCreateTree(string& str, int& i)
{
if (str[i] == '#')
return nullptr;
TreeNode *head = new TreeNode(str[i]);
i++;
head->left = PreOrderCreateTree(str, i);
i++;
head->right = PreOrderCreateTree(str, i);
return head;
}
这里需要注意,使用先序去创建二叉树是可以的,如果想要使用后序或者中序的字符串是不行的,因为后序或者中序无法唯一确定一颗二叉树,所以想要创建二叉树还可以使用中序和后序字符串去创建或者前序和中序去创建。
2. 编写函数,实现二叉树的中序递归遍历算法。
//中序递归遍历(左根右)
void PastOrderShow1(TreeNode* head)
{
if (head != nullptr)
{
PastOrderShow1(head->left);
cout << head->val << " ";
PastOrderShow1(head->right);
}
}
递归遍历非常简单,只需要记住不同遍历方法,遍历结点的顺序即可
3. 编写函数,实现二叉树的中序非递归遍历算法
//中序非递归遍历
void PastOrderShow2(TreeNode* head)
{
if (head == nullptr)
return;
stack<TreeNode*>st;
while (!st.empty()||head)
{
while (head)
{
st.push(head);
head = head->left;
}
head = st.top();
cout << head->val << " ";
st.pop();
head = head->right;
}
}
非递归遍历需要利用栈(这里我使用的是C++语言,所以使用的是STL容器中的stack,一个先进后出的容器)去完成,先将左孩子结点依次入栈,然后取栈顶元素进行遍历,在去将当前结点的右孩子依次入栈,其实细心的读者也会发现,这也就是中序遍历结点的顺序。
4. 编写函数,借助队列实现二叉树的层次遍历算法
void LevelShow(TreeNode* head)
{
if (head == nullptr)
return;
queue<TreeNode*>qu;
qu.push(head);
while (!qu.empty())
{
TreeNode* top = qu.front();
cout << top->val << " ";
qu.pop();
if (top->left)
qu.push(top->left);
if (top->right)
qu.push(top->right);
}
}
这里也是使用了一个STL中的一个先进先出的容器queue,通过每次去对头结点,然后读取,并且将该结点的左右孩子入队,从而达到一个层次遍历的效果
5. 编写函数,求二叉树的高度
int TreeHigh(TreeNode* root)
{
if (root == nullptr)
return 0;
int lefthigh = TreeHigh(root->left);
int righthigh = TreeHigh(root->right);
return lefthigh > righthigh ? lefthigh + 1 : righthigh + 1;
}
这里非常简单,利用递归去求得左右子树的高度,从而选取最大高度再加上根节点即可。
6. 编写函数,求二叉树的结点个数
int CountNode(TreeNode* root)
{
if (root == nullptr)
return 0;
int lefthigh = CountNode(root->left)+1;
int righthigh = CountNode(root->right)+1;
return lefthigh+righthigh-1;
}
利用递归去求左右子树的节点个数,然后减去一个重复的根节点,本题也可以使用的一个方法就是在遍历的途中(递归,非递归都可以)去计数也可以
7. 编写函数,求二叉树的叶子个数
int CountLeafNode(TreeNode* root)
{
if (root == nullptr)
return 0;
if (root->left == nullptr&&root->right == nullptr)
return 1;
int lefthigh = CountLeafNode(root->left);
int righthigh = CountLeafNode(root->right);
return lefthigh + righthigh;
}
还是用过递归的方法去得到叶子结点(左右子树都为空)的个数
8. 编写函数,交换二叉树每个结点的左子树和右子树
void Swap(TreeNode* root)
{
if (root == nullptr)
return;
TreeNode* cur;
if (root->left&&root->right)
{
cur = root->left;
root->left = root->right;
root->right = cur;
}
else if (root->left == nullptr&&root->right)
{
root->left = root->right;
root->right = nullptr;
}
else if (root->right == nullptr&&root->left)
{
root->right = root->left;
root->left = nullptr;
}
Swap(root->left);
Swap(root->right);
}
这里先去根据不同情况交换根节点的左右子树,然后递归交换下面的结点
9. 编写一个主函数,在主函数中设计一个简单的菜单,分别调试上述算法
主函数大家自行练习
四、实验类型或性质
验证性
五、实验开出要求
必做
六、实验所需仪器设备
1.计算机
2.相关软件(如C,C++,PASCAL,VC,DELPHI等等)
七、实验所用材料
计算机耗材