数据结构 -> 后序创建二叉树

 
 
二叉树的前,中,后序遍历 以及通过补‘#’字符补充二叉树空分支,按照前序顺序构造二叉树,
这些都比较简单,我这就不过多地赘述;直接贴代码
 
 
#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;
}

猜你喜欢

转载自blog.csdn.net/desporado/article/details/80384041