二叉树的一些简单的概念就不在这里陈诉了 先说下二叉树的三种遍历方式
*前序遍历:先访问根节点 在访问左孩子 最后访问右孩子(第一个数为树的根节点)
*中序遍历:先访问左孩子 在访问根节点 最后访问右孩子(根节点在序列中间 根节点左边的为左子树的值)
*后序遍历:先访问左孩子 在访问右孩子 最后访问根节点 (根节点在序列数组最后,由中序确定左右子树的范围)
当我们知道前序遍历 和中序遍历后 或者中序遍历和后序遍历后 就能够唯一确定一个树 若只是前序遍历和后续遍历则不能确定唯一的二叉树
下面给出的为一个完整的二叉树的构建与三种遍历的递归过程
*已知某二叉树的前序遍历为{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;
}