由前序遍历和中序遍历重建二叉树
思路分析:
代码实现:
#include <iostream>
#include <Windows.h>
#include <assert.h>
using namespace std;
template <class T>
struct BinaryTreeNode
{
T _data; //节点的值
BinaryTreeNode<T>* _left;
BinaryTreeNode<T>* _right;
BinaryTreeNode(const T& data)
:_data(data)
, _left(NULL)
, _right(NULL)
{}
};
template <class T>
class BinaryTree
{
typedef BinaryTreeNode<T> Node;
public:
BinaryTree()
:_root(NULL)
{}
~BinaryTree()
{}
BinaryTree(T* prev, T* in, size_t size)
{
assert(prev && in);
_ReBulitBinaryTree(prev, in, size, _root);
}
void PostOrder() //后序遍历
{
cout << "后序遍历:" << "";
_PostOrder(_root);
cout << endl;
}
protected:
void _ReBulitBinaryTree(T* prev, T* in, size_t size, Node*& root) //重建二叉树
{
if (size <= 0)
{
return; //递归出口
}
if (root == NULL)
{
root = new Node(prev[0]); //每次遍历子树,根节点均为前序的第一个元素
}
int index = 0;
while (index < size) //此过程为在中序中找到根节点划分左右子树
{
if (in[index] == prev[0])
{
break;
}
else
{
++index;
}
}
//此时出了循环之后,可能是找到了元素,也能找不到,只有找到了才继续
if (index < size)
{
size_t sizeL = index; //左子树的元素个数
size_t sizeR = size - index - 1; //右子树的元素个数
_ReBulitBinaryTree(prev + 1, in, sizeL, root->_left); //递归重建左子树
_ReBulitBinaryTree(prev+index+1, in+index+1, sizeR, root->_right); //递归重建右子树
}
}
void _PostOrder(Node* root) //后序遍历
{
if (root == NULL)
{
return;
}
_PostOrder(root->_left);
_PostOrder(root->_right);
cout << root->_data << " ";
}
protected:
Node* _root; //根节点
};
#include "ReBulitBinaryTree.h"
void TestReBulitBinaryTree()
{
int prev[] = { 100, 60, 40, 80, 140, 120, 160 };
int in[] = { 40, 60, 80, 100, 120, 140, 160 };
size_t size1 = sizeof(prev) / sizeof(prev[0]);
size_t size2 = sizeof(in) / sizeof(in[0]);
if (size1 == size2)
{
BinaryTree<int> pp(prev, in, size1);
pp.PostOrder();
}
else
cout << "error" << endl;
}
int main()
{
TestReBulitBinaryTree();
system("pause");
return 0;
}