二叉树的前,中,后序遍历 以及通过补‘#’字符补充二叉树空分支,按照前序顺序构造二叉树,
这些都比较简单,我这就不过多地赘述;直接贴代码
#include "stdafx.h"
#include<iostream>
using namespace std;
typedef char DataType;
typedef struct Node
{
DataType data; //数据域
struct Node * lchild;
struct Node * rchild; //结点的左右子数指针
}BTNode; //二叉树结点类型
//初始化空二叉树
void TreeInit(BTNode * &root);
//按照前序遍历序列建立二叉树
void CreateBTree_Pre(BTNode * &root, DataType Array[]);
//前序遍历二叉树
void PreOrder(BTNode * root);
//中序遍历二叉树
void InOrder(BTNode * root);
//后序遍历二叉树
void PostOrder(BTNode * root);
//计算二叉树的深度
int BTreeDepth(BTNode * root);
//释放二叉树中所有结点
void ClearBTree(BTNode * &root);
#include"stdafx.h"
#include"BiTree.h"
//初始化空二叉树
void TreeInit(BTNode * &root)
{
root = NULL;
}
//按照前序遍历序列建立二叉树
void CreateBTree_Pre(BTNode * &root, DataType Array[])
{
static int count = 0; //静态变量count
char item = Array[count]; //读取Array[]数组中的第count 元素
count++;
if (item == '#')
{
root = NULL;
}
else
{
root = new BTNode;
root->data = item;
CreateBTree_Pre(root->lchild, Array); //建立左子树
CreateBTree_Pre(root->rchild, Array); //建立右子树
}
}
//前序遍历二叉树
void PreOrder(BTNode * root)
{
if (root != NULL)
{
cout << root->data; //访问根结点
PreOrder(root->lchild); //前序遍历左子树
PreOrder(root->rchild); //前序遍历右子树
}
}
//中序遍历二叉树
void InOrder(BTNode * root)
{
if (root != NULL)
{
InOrder(root->lchild); //中序遍历左结点
cout << root->data; //访问根结点
InOrder(root->rchild); //中序遍历右子树
}
}
//后序遍历二叉树
void PostOrder(BTNode * root)
{
if (root != NULL)
{
PostOrder(root->lchild); //后序遍历左结点
PostOrder(root->rchild); //后序遍历右子树
cout << root->data; //访问根结点
}
}
//释放二叉树中所有结点
void ClearBTree(BTNode * &root)
{
if (root != NULL)
{
ClearBTree(root->lchild);
ClearBTree(root->rchild);
delete root;
root = NULL;
}
}
//计算二叉树的深度
int BTreeDepth(BTNode * root)
{
if (root == NULL)
{
return 0;
}
else
{
int depl = BTreeDepth(root->lchild);
int depr = BTreeDepth(root->rchild);
if (depl > depr)
{
return depl + 1;
}
else
{
return depr + 1;
}
}
#include "stdafx.h"
#include"BiTree.h"
int main()
{
BTNode *root;
DataType A[] = "ABD##E##CF#G###"; //以“#”补充空分支后的某个遍历序列
TreeInit(root); //初始化空二叉树
CreateBTree_Pre(root, A); //以前序遍历序列建立二叉树
cout << "中序遍历序列:";
InOrder(root);
cout << endl; //输出中序遍历树
cout << "后序遍历序列:";
PostOrder(root);
cout << endl; //输出后序遍历树
cout << "深度:" << BTreeDepth(root) << endl; //计算二叉树深度
system("pause");
return 0;
}

配合这张图片以及测试代码,我相信应该比较好理解二叉树的三种遍历顺序以及前序构造二叉树;
好,下面我们重点来看看另外一种构建二叉树的方式:后序构造二叉树
首先呢,我们得清楚一个概念,我所谓的构建二叉树的方式,是通过把二叉树的后序遍历得到的
结果存放在一个字符串中(用‘#’表示二叉树的空结点),再依据这个字符串构建出相应的二叉树
ok.清楚了我们要做什么以后,开始动手!
参照前序遍历顺序,以及后序遍历的特点,很自然的认为这通过两种方式构建树的代码应该也是非常
相似的,只需要把前序遍历代码中生成根结点的部分放在生成左右孩子之后,应该能轻松写出后序创
建二叉树的函数
//按照后序遍历序列建立二叉树 --error
void CreateBTree_Post(BTNode * &root, DataType Array[])
{
static int count = 0; //静态变量count
char item = Array[count]; //读取Array[]数组中的第count 元素
count++;
if (item == '#')
{
root = NULL;
}
else
{
CreateBTree_Post(root->lchild, Array); //建立左子树
CreateBTree_Post(root->rchild, Array); //建立右子树
root = new BTNode;
root->data = item;
}
}
程序一跑,马上就断掉了。。。
调试跟进后发现,后序创建二叉树,无论如何,第一个位置一定是‘#’
(后序遍历只有遇到空结点才会停止往下延伸),那么条件if(item == '#')root == NULL;
成立,程序直接断掉。
那这就麻烦了,不仅后序创建二叉树无解,中序创建二叉树也无解(他们都先检索左孩子
直到遇见空结点才返回)
显然,这种思路是走不通的;计算机不像我们人一样,可以通过对叶子结点的分析,一步
一步反推出整棵树的形状,你只有把所有数据都传给它,它才能帮你分析出树的模样;换
句话说,你只有确确实实地生成了一棵树,计算机才知道它到底长什么样子,而不是像我
们人类通过一样能够想象在头脑中描绘出树的模样
很自然的,想让计算机和我们一样通过叶子反推出根这一方法行不通。那么我们就让这棵
树从根部往下生长!
通过后序遍历的特点我们可以发现:生成树的字符串的最后一个字符,代表的就是它的根结
点,倒数第二个就是它的右孩子。。。很容易发现,如果我们从字符串后面开始推,按照
根结点 -> 右结点 ->左节点 的顺序就能通过递归构造出一棵二叉树了!
//按照后序遍历序列建立二叉树
void CreateBTree_Post2(BTNode * &root, DataType Array[])
{
static int count = strlen(Array); //静态变量count
char item = Array[count - 1]; //读取Array[]数组中的第count 元素
count--;
if (item == '#')
{
root = NULL;
}
else
{
root = new BTNode;
root->data = item;
CreateBTree_Post2(root->rchild, Array); //建立右子树
CreateBTree_Post2(root->lchild, Array); //建立左子树
}
}
测试代码:
int main()
{
BTNode *root;
TreeInit(root); //初始化空二叉树
DataType A[] = "##C##DB##EA"; //以“#”补充空分支后的某个遍历序列
CreateBTree_Post2(root, A); //以前序遍历序列建立二叉树
cout << "前序遍历序列:";
PreOrder(root);
cout << endl; //输出前序遍历树
cout << "中序遍历序列:";
InOrder(root);
cout << endl; //输出中序遍历树
cout << "深度:" << BTreeDepth(root) << endl; //计算二叉树深度
system("pause");
return 0;
}
