剑指offer 6---由前序遍历和中序遍历重建二叉树

由前序遍历和中序遍历重建二叉树

思路分析:

           

代码实现:

#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;
}







  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值