二叉树的基本运算
一、实验目的
1、使学生熟练掌握二叉树的逻辑结构和存储结构。
2、熟练掌握二叉树的各种遍历算法。
二、实验内容
题目一:二叉树的基本操作实现(必做题)
[问题描述]
建立一棵二叉树,试编程实现二叉树的如下基本操作:
1. 按先序序列构造一棵二叉链表表示的二叉树T;
2. 对这棵二叉树进行遍历:先序、中序、后序以及层次遍历,分别输出结点的遍历序列;
3. 求二叉树的深度/结点数目/叶结点数目;(选做)
4. 将二叉树每个结点的左右子树交换位置。(选做)
[基本要求]
从键盘接受输入(先序),以二叉链表作为存储结构,建立二叉树(以先序来建立)。
[测试数据]
如输入:ABCффDEфGффFффф(其中ф表示空格字符)
则输出结果为
先序:ABCDEGF
中序:CBEGDFA
后序:CGEFDBA
层序:ABCDEFG
[选作内容]
采用非递归算法实现二叉树遍历。
1、总体设计(设计思想)
本题描述直白,即二叉树的基本操作,因此我们只需要根据输入的数据建立一棵树,然后用不同的方法去遍历这棵树。
2、详细设计及重要代码
当用户输入数据的时候,采用先根再左后右的顺序建立这棵树,以“#”代表空节点,先序、中序、后序遍历都比较简单,关键是层序遍历,层序遍历需要结合队列来完成,具体代码如下:
intprint_by_level(BiTree T) //层序遍历
{
queue<BiTNode>aa;
BiTNode q;
if(T)
{
aa.push(*T); //根节点进队
while(!aa.empty())
{
q=aa.front(); //获取队列第一个元素
aa.pop(); //弹出队列第一个元素
cout<<q.data<<"->";
if(q.lchild!=NULL)aa.push(*q.lchild); //若果有左孩子,左孩子入队
if(q.rchild!=NULL)aa.push(*q.rchild); //如果有右孩子,右孩子入队
}
}
else
return (OK);
}
3、功能展示及截图
4、程序清单
#include<queue> #include<malloc.h> #include<conio.h> #include<iostream> using namespace std; #define OK 1 #define ERROR 0 typedef char TElemType; typedef struct BiTNode //定义节点结构体 { TElemType data; struct BiTNode *lchild,*rchild; }BiTNode, *BiTree; int CreateBiTree(BiTree &T) //创建二叉树 { TElemType ch; cout<<"请输入数据(char型字符)(“#”代表NULL) : "; cin>>ch; if(ch=='#') T=NULL; else { if(!(T=(BiTNode *)malloc(sizeof(BiTNode)))) { cout<<"Overflow!"; //申请内存失败 return (ERROR); } T->data=ch; CreateBiTree(T->lchild); //创建左孩子 CreateBiTree(T->rchild); //创建右孩子 } return (OK); } int PreOrderTraverse(BiTree T) //先序遍历 { if(T) { cout<<T->data<<"->"; //访问根节点 if (PreOrderTraverse(T->lchild)) //如果有左孩子,就访问左孩子 if (PreOrderTraverse(T->rchild)) //如果有有孩子,就访问有孩子 return (OK); return (ERROR); } else return (OK); } int InOrderTraverse(BiTree T) //中序遍历 { if(T) { if (InOrderTraverse(T->lchild)) //一直向左访问直到叶子节点 { cout<<T->data<<"->"; //访问根节点 if(InOrderTraverse(T->rchild)) //一直向右访问直到叶子节点 return (OK); } return (ERROR); } else return (OK); } int PostOrderTraverse(BiTree T) //后序遍历 { if(T) { if (PostOrderTraverse(T->lchild)) //一直向左访问直到叶子节点 if(PostOrderTraverse(T->rchild)) //一直向右访问直到叶子节点 { cout<<T->data<<"->"; //访问根节点 return (OK); } return (ERROR); } else return (OK); } int print_by_level(BiTree T) //层序遍历 { queue<BiTNode>aa; BiTNode q; if(T) { aa.push(*T); //根节点进队 while(!aa.empty()) { q=aa.front(); //获取队列第一个元素 aa.pop(); //弹出队列第一个元素 cout<<q.data<<"->"; if(q.lchild!=NULL) aa.push(*q.lchild); //若果有左孩子,左孩子入队 if(q.rchild!=NULL) aa.push(*q.rchild); //如果有右孩子,右孩子入队 } } else return (OK); } int main() { BiTree T; cout<<"Please input data to create BiTree:"<<endl; if(CreateBiTree(T)) //创建二叉树并判断是否创建成功 cout<<endl<<"创建二叉树成功! "; else cout<<endl<<"创建二叉树失败! "; cout<<endl<<endl<<"...OK!..."; cout<<endl<<endl<<"先序遍历:"<<endl; PreOrderTraverse(T); cout<<endl<<endl<<"中序遍历:"<<endl; InOrderTraverse(T); cout<<endl<<endl<<"后序遍历:"<<endl; PostOrderTraverse(T); cout<<endl<<endl<<"层序遍历:"<<endl; print_by_level(T); cout<<endl<<endl; return 0; }