二叉树的建立与遍历

二叉树的一些简单的概念就不在这里陈诉了  先说下二叉树的三种遍历方式

*前序遍历:先访问根节点 在访问左孩子 最后访问右孩子(第一个数为树的根节点)
*中序遍历:先访问左孩子 在访问根节点 最后访问右孩子(根节点在序列中间 根节点左边的为左子树的值)
*后序遍历:先访问左孩子 在访问右孩子 最后访问根节点 (根节点在序列数组最后,由中序确定左右子树的范围)


当我们知道前序遍历 和中序遍历后 或者中序遍历和后序遍历后 就能够唯一确定一个树 若只是前序遍历和后续遍历则不能确定唯一的二叉树

下面给出的为一个完整的二叉树的构建与三种遍历的递归过程

*已知某二叉树的前序遍历为{1,2,4,7,3,5,6,8},中序遍历为{4,7,2,1,5,3,8,6}   请重建该二叉树
#include <iostream>

using namespace std;

struct BinaryTreeNode
{
	int   m_nValue;
	struct BinaryTreeNode *m_pLeft;
	struct BinaryTreeNode *m_pRight;
};

/*节点的构建(前序,中序)
*startPreorder 子树前序遍历数组的开始地址
*endPreorder   子树前序遍历数组的结束地址
*startInorder  子树中序遍历数组的开始地址
*endInorder    子树中序遍历数组的开始地址
*/
BinaryTreeNode *ConstructCore(int *startPreorder,int *endPreorder,int *startInorder,int *endInorder)
{
	//前序遍历的第一个数字为根节点的值
	int rootValue = startPreorder[0];
	BinaryTreeNode *root = new BinaryTreeNode();
	root->m_nValue = rootValue;
	root->m_pLeft = root->m_pRight = NULL;
	//返回退出条件(前序遍历到叶子节点)
	if(startPreorder == endPreorder)   // 因为调用到最后ConstructCore的4个参数值相等
	{   
		if(startInorder == endInorder && *startPreorder == *startInorder)
			return root;
		else
			throw std::exception("Invalud input.");
	}

	//在中序遍历中找到根节点的值
	int *rootInorder = startInorder;
	while(rootInorder <= endInorder && *rootInorder != rootValue)
		++rootInorder;
	if(rootInorder == endInorder && *rootInorder != rootValue)    //安全性考虑找不到抛出异常
		throw std::exception("Invalid input:");

	//由中序遍历得到左子树的长度
	int leftLength = rootInorder - startInorder;
	int *leftPreorderEnd = startPreorder + leftLength;
	if(leftLength > 0)
	{
		//构建左子树
		root->m_pLeft = ConstructCore(startPreorder+1,leftPreorderEnd,startInorder,rootInorder-1);
	}
	if(leftLength < endPreorder - startPreorder)
	{
		//构建右子树
		root->m_pRight = ConstructCore(leftPreorderEnd+1,endPreorder,rootInorder+1,endInorder);
	}
	return root;
}
/*构建二叉树
*preorder前序遍历数组的首地址
*inorder中序遍历数组的首地址
*length数组长度
*/
struct BinaryTreeNode *Construct(int *preorder,int *inorder,int length)
{
	if(preorder == NULL ||inorder == NULL ||length <= 0)
		return NULL;
	return ConstructCore(preorder,preorder+length-1,inorder,inorder+length-1);
}

//前序遍历递归算法
void PreOrderTraverse(BinaryTreeNode *T)
{
	if(T == NULL)
		return ;
	cout<<T->m_nValue<<" ";
	PreOrderTraverse(T->m_pLeft);
	PreOrderTraverse(T->m_pRight);
}
//中序遍历递归算法
void InOrderTraverse(BinaryTreeNode *T)
{
	if(T == NULL)
		return ;
	InOrderTraverse(T->m_pLeft);
	cout<<T->m_nValue<<" ";
	InOrderTraverse(T->m_pRight);
}

//后序遍历递归算法
void PostOrderTraverse(BinaryTreeNode *T)
{
	if(T == NULL)
		return ;
	PostOrderTraverse(T->m_pLeft);
	PostOrderTraverse(T->m_pRight);
	cout<<T->m_nValue<<" ";
}
int main()
{
	int PreStr[]= {1,2,4,7,3,5,6,8};
	int InStr[] = {4,7,2,1,5,3,8,6};
	int Length = sizeof(PreStr)/sizeof(PreStr[0]);
	//int LenthIn = sizeof(InStr)/sizeof(InStr[0]);

	//建立二叉树(由中序遍历和前序遍历)
	struct BinaryTreeNode *root = Construct(PreStr,InStr,Length);

	//二叉树的前序遍历递归算法
	PreOrderTraverse(root);
	cout<<endl;

	//二叉树的中序遍历递归算法
	InOrderTraverse(root);
	cout<<endl;

	//二叉树的后InOrderTraverse序遍历递归算法
	PostOrderTraverse(root);
	cout<<endl;
	
    return 0;
}



猜你喜欢

转载自blog.csdn.net/asia66/article/details/81005901