文章目录
0. 前言
二叉树的顺序存储结构就是用一维数组存储二叉树中的节点,并且节点的存储位置,
也就是数组的下标要能体现节点之间的逻辑关系
(存储的方式以数组存储,读取以二叉树的特点输出)
0.1 二叉树的结构体
typedef struct MyTree
{
char data;
struct MyTree *Lchild, *Rchild;
MyTree();
~MyTree();
} *MyTreeNode;
1.二叉树的遍历
二叉树的遍历是指从二叉树的某个节点出发,按照某种次序依次访问二叉树中的所有节点,使得每个节点被访问一次,且仅被访问一次
1.1 二叉树前序遍历(根→左→右)
下图遍历结果:ABDGHCEIF
执行代码
void preOrderTraverse(MyTreeNode T, int level)
{
if (T)
{
visit(T->data, level + 1);//访问根节点
preOrderTraverse(T->Lchild, level + 1);//左子树遍历
preOrderTraverse(T->Rchild, level + 1);//右子树遍历
}
}
1.2 二叉树的中序遍历(左-根-右)
遍历结果:
中序遍历代码
void MidOrderTraverse(MyTreeNode T, int level)
{
if (T)
{
MidOrderTraverse(T->Lchild, level + 1);//左子树遍历
visit(T->data, level + 1);//访问根节点
MidOrderTraverse(T->Rchild, level + 1);//右子树遍历
}
}
1.3 后序遍历(左-右-根)
遍历结果:GHDBIEFCA
后序遍历代码
void PostOrderTraverse(MyTreeNode T, int level)
{
if (T)
{
PostOrderTraverse(T->Lchild, level + 1);//左子树遍历
PostOrderTraverse(T->Rchild, level + 1);//右子树遍历
visit(T->data, level + 1);//访问根节点
}
}
1.4 二叉树层序遍历结果
层序遍历代码
void LevelOrderTraverse(MyTreeNode T)
{
queue<MyTreeNode> s;
MyTreeNode p;
MyTreeNode q;
p = T;
if (p == NULL)
{
cout << "tree is empty" << endl;
return;
}
s.push(p);//将根节点入队
while (!s.empty())
{
//根节点入队
p = s.front();//队列s头部压入p中
s.pop();
//左节点入队
if (NULL != p->Lchild)
{
q = p->Lchild;
s.push(q);
}
if (NULL != p->Rchild)
{
q = p->Rchild;
s.push(q);
}
cout << p->data << endl;
}
}
2. 完整代码
#include<iostream>
#include<stack>
#include<queue>//单纯的队列容器
using namespace std;
typedef struct MyTree
{
char data;
struct MyTree *Lchild, *Rchild;
MyTree();
~MyTree();
} *MyTreeNode;
//MyTree()函数实现
MyTree::MyTree()
{
data = '0';
Lchild = Rchild = nullptr;
}
//MyTree()函数实现
MyTree::~MyTree()
{
if (Lchild != nullptr)
delete[] Lchild;
Lchild = nullptr;
if (Rchild != nullptr)
delete[] Rchild;
Rchild = nullptr;
}
//创建一颗二叉树,约定用户遵照前序遍历的方式输入数据
void CreatMyTree(MyTreeNode & BiTree)
{
char cTreeData;
cin >> cTreeData;
if ('#' == cTreeData)//# 表示结束
{
cTreeData = NULL;
}
else
{
BiTree = new MyTree;
BiTree->data = cTreeData;
CreatMyTree(BiTree->Lchild);
CreatMyTree(BiTree->Rchild);
}
}
//访问二叉树的具体节点的函数
void visit(char cTree, int level)
{
printf("%c 位于第 %d 层\n", cTree, level);
}
//前序遍历二叉树-递归
void preOrderTraverse(MyTreeNode T, int level)
{
if (T)
{
visit(T->data, level + 1);//访问根节点
preOrderTraverse(T->Lchild, level + 1);//左子树遍历
preOrderTraverse(T->Rchild, level + 1);//右子树遍历
}
}
//中序遍历二叉树-递归
void MidOrderTraverse(MyTreeNode T, int level)
{
if (T)
{
MidOrderTraverse(T->Lchild, level + 1);//左子树遍历
visit(T->data, level + 1);//访问根节点
MidOrderTraverse(T->Rchild, level + 1);//右子树遍历
}
}
//后序遍历二叉树-递归
void PostOrderTraverse(MyTreeNode T, int level)
{
if (T)
{
PostOrderTraverse(T->Lchild, level + 1);//左子树遍历
PostOrderTraverse(T->Rchild, level + 1);//右子树遍历
visit(T->data, level + 1);//访问根节点
}
}
//层次遍历二叉树
void LevelOrderTraverse(MyTreeNode T)
{
queue<MyTreeNode> s;
MyTreeNode p;
MyTreeNode q;
p = T;
if (p == NULL)
{
cout << "tree is empty" << endl;
return;
}
s.push(p);//将根节点入队
while (!s.empty())
{
//根节点入队
p = s.front();//队列s头部压入p中
s.pop();
//左节点入队
if (NULL != p->Lchild)
{
q = p->Lchild;
s.push(q);
}
if (NULL != p->Rchild)
{
q = p->Rchild;
s.push(q);
}
cout << p->data << endl;
}
}
int main()
{
//输入实例:ABDH##I##E#J##CF#K##G###
MyTreeNode tree;//创建二叉树指针
cout << "请输入一个二叉树序列:" << endl;
CreatMyTree(tree);
//打印前序遍历的结果
cout << endl << "前序遍历的结果为:" << endl;
preOrderTraverse(tree, 0);
//打印中序遍历的结果
cout << endl << "中序遍历的结果为:" << endl;
MidOrderTraverse(tree, 0);
//打印后序遍历的结果
cout << endl << "后序遍历的结果为:" << endl;
PostOrderTraverse(tree, 0);
cin.get();
cin.get();
cin.get();
return 0;
}
3.总结
3.1该如何理解构造析构函数的存在:
因为类或者结构体的存在,相当于重新定义一个数据类型,则个数据类型不仅仅在像通常所理解的整数,字符类型,而是包含了多种特征的一个类型。因此构造函数的存在就是用来给这样的一个数据类型(对象)来初始化(因为其它数据类型在使用时也需要初始化,计算机内部要给变量创建内存空间并赋值,不初始化会导致内存错误);而析构函数的存在就像是使用完指针,将指针的内存释放一样,也需要释放对象的内存空间。
3.2 C++编程的一般特点:
在解决一个实际问题的时候,并不像通常所理解的那样,直接对问题求解,因为计算机内部需要对代码进行编译,也就是说需要开辟内存,释放内存等一系列操作,因而在解决一个问题时通常需要准备工作(包括:定义变量、指针申请内存、文件打开预定义、类或结构体对象初始化);在解决完问题时,也需要同计算机内存进行释放,工作包括(指针释放、文件关闭、类或结构体变量析构)
3.3 中序遍历过程图示
已知的二叉树组成
中序遍历图示
4.参考文章
https://blog.csdn.net/wjwfighting/article/details/81670229
https://blog.csdn.net/shell33168/article/details/88645346
https://www.cnblogs.com/didiaodidiao/p/9128762.html