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

  对于二叉树,在此我不做过多讲解,如有不懂,请参照一下链接点击打开链接

 1、在此二叉树的定义:

struct BinaryTreeNode  
{  
    BinaryTreeNode<T> *_Left;  
    BinaryTreeNode<T> *_Right;  
    T _data;  
public:  
    BinaryTreeNode(const T& x)  
        :_Left(NULL)  
        , _Right(NULL)  
        , _data(x)  
    {}  
};  
  
template<class T>  
class BinaryTree  
{  
    typedef BinaryTreeNode<T> Node;  
public:  
    BinaryTree()  
        :_root(NULL)  
    {}  
}  
2、由前序遍历和中序遍历重建二叉树
//二叉树前序遍历中,第一个元素总是根节点的值,
//中序遍历,左子树的结点的值位于根节点值得左边,
//右子树的节点的值位于根节点值得右边。

//1、如果前序遍历为空或中序遍历为空或结点个数小于等于0,返回NULL;
//2、创建根节点,前序遍历的第一个数据就是根节点的数据,在中序遍历中找到根节点位置

//分别得知左子树和右子树的前序和中序遍 历序列,重建左右子树。



递归形式实现 1:

Node* RebuildBinaryTree(T* PrevOrder, T* InOrder, int num)
	{
		if (PrevOrder == NULL || InOrder == NULL || num <= 0)
		{
			return NULL;
		}
		return  ConstructCore(PrevOrder, PrevOrder + num - 1, InOrder, InOrder + num - 1);
	}
  Node* ConstructCore(int* startPrevorder, int* endPrevorder,
			         int* startInorder, int* endInorder)
		{
	       Node* root = new Node(startPrevorder[0]);
		   root->_Left = root->_Right = NULL;
		   if (startPrevorder == endPrevorder)
		   {
			   if (startInorder ==endInorder&&*startPrevorder == *startInorder)
			   {
				   return root;
			   }
		   }
		   //中序遍历找根节点
		   int* rootInorder = startInorder;
		   while (rootInorder < endInorder && *rootInorder != root->_data)
		   {
			   ++rootInorder;
		   }
		   if (rootInorder == endInorder && *rootInorder != root->_data)
		   {
				cout << "invalid input" << endl;

		   }

		   int leftlength = rootInorder - startInorder;
		   int *leftPrevlengthend = startPrevorder + leftlength;

		   if (leftlength > 0)
		   {
			   root->_Left = ConstructCore(startPrevorder + 1, leftPrevlengthend, startInorder, rootInorder - 1);
		   }
		   if (leftlength < endPrevorder - startPrevorder)
		   {
			   root->_Right = ConstructCore(leftPrevlengthend + 1, endPrevorder,  rootInorder +1,endInorder);
		   }

		   return root;
		}

递归形式2

Node* reConstructBinaryTree(vector<int> pre, vector<int> in) 
	{
		int len = in.size();
		int len2 = pre.size();
		if (pre.size() == 0 || in.size() == 0 || len<= 0)
			{
					return NULL;
			}

		vector<int> startpre, endpre, startin, endin;
		Node* root = new Node(pre[0]);
		root->left = NULL;
		root->right = NULL;
		if (len == 1 && len2 == 1)
		{
			if (pre[0] != in[0])
				cout << "invalued input" << endl;
		}
		int i = 0;
		//中序找根节点
		int rootin = -1;
		for (i = 0; i<len; ++i)
		{
			if (in[i] == pre[0])
			{
				rootin = i;
				break;
			}
		}
		if (rootin == -1) //当中序遍历完后还没找到根节点
		{
			return NULL;
		}
		for (i = 0; i<rootin; ++i)//左边
		{
			startin.push_back(in[i]);
			startpre.push_back(pre[i + 1]);
		}
		for (i = rootin + 1; i<len; i++)//右边
		{
			endin.push_back(in[i]);
			endpre.push_back(pre[i]);
		}
		root->left = reConstructBinaryTree(startpre, startin);
		root->right = reConstructBinaryTree(endpre, endin);
		return root;
	}




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值