已知前序中序,重建二叉树(加7种遍历的方式)




#include <iostream>
#include <stack>
#include <queue>
using namespace std;

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

//void CreateTree(BinaryTreeNode *  & node)
//{
//	char temp; 
//	cout << "输入改节点的数据" << endl;
//	cin >> temp;
//	if (temp == 'c')
//	{
//		node = NULL;
//	}
//	else
//	{
//		node = new BinaryTreeNode;
//		node->m_nValue = temp;
//		CreateTree(node->m_pLeft);
//		CreateTree(node->m_pRight);
//	}
//}

BinaryTreeNode * ConstructCore(int * beginPreoder, int * endPreorder, int * beginInorder, int * endInorder)
{
	int rootValue = beginPreoder[0];  //根节点总为当前前序数组的首位
	BinaryTreeNode * root = new BinaryTreeNode();
	root->m_nValue = rootValue;
	root->m_pLeft = root->m_pRight = NULL;  

	if (beginPreoder == endPreorder) //新前序和中序中只有一个节点则返回
	{
		if (beginInorder == endInorder && *beginInorder == *beginPreoder)  
			return root;
		else
			throw std::exception("Invalid input.");
	}

	//在中序遍历中找到根节点的值
	int * rootInorder = beginInorder;
	while (rootInorder <= endInorder && *rootInorder != rootValue) ++rootInorder;

	if (rootInorder == endInorder && *rootInorder != rootValue)
		throw std::exception("Invalid input . ");

	int leftLength = rootInorder - beginInorder; //左子树的长
	int * leftPreorderEnd = beginPreoder + leftLength; //前序数组中 左子树的末尾

	if (leftLength > 0)  //左子树不为空,创建左子树
	{                                   
		root->m_pLeft = ConstructCore(beginPreoder + 1, leftPreorderEnd, beginInorder, rootInorder - 1);
	}
	if (leftLength < endPreorder - beginPreoder) //创建右子树
	{
		root->m_pRight = ConstructCore(leftPreorderEnd + 1, endPreorder, rootInorder + 1, endInorder);
	}
	return root;
}

//通过前序遍历和中序遍历来重建二叉树
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  PreOrderVisit(BinaryTreeNode * T)
{
	if (T)
	{
		cout << T->m_nValue << " "; 
		PreOrderVisit(T->m_pLeft);
		PreOrderVisit(T->m_pRight);
	}
}

//二叉树递归中序遍历
void  InOrderVisit(BinaryTreeNode * T)
{
	if (T)
	{
		InOrderVisit(T->m_pLeft);
		cout << T->m_nValue << " ";
		InOrderVisit(T->m_pRight);
	}
}

//二叉树递归后序遍历
void  LastOrderVisit(BinaryTreeNode * T)
{
	if (T)
	{
		LastOrderVisit(T->m_pLeft);
		LastOrderVisit(T->m_pRight);
		cout << T->m_nValue << " ";
	}
}

//层序二叉树遍历
void LevelOrderVisit(BinaryTreeNode *T)
{
	queue <BinaryTreeNode *> Q; 
	if (!T) return; 
	Q.push(T);
	BinaryTreeNode * temp = NULL; 
	while (!Q.empty())
	{
		temp = Q.front(); 
		cout << temp->m_nValue << " "; 
		Q.pop();
		if (temp->m_pLeft)
			Q.push(temp->m_pLeft);
		if (temp->m_pRight)
			Q.push(temp->m_pRight);
	}
}

//非递归前序遍历
void NoPreRecursiveVist(BinaryTreeNode *T)
{
	stack <BinaryTreeNode * >  S; //用来保存节点的栈 
	BinaryTreeNode * p; 
	p = T; 
	while (!S.empty() || p)
	{
		if (p)
		{
			S.push(p);
			cout << p->m_nValue << " "; 
			p = p->m_pLeft;
		}
		else
		{
			p = S.top();
			S.pop();
			p = p->m_pRight;
		}
	}
}

//非递归中序遍历
void NoInRecursiveVist(BinaryTreeNode * T)
{
	stack <BinaryTreeNode * > S; 
	BinaryTreeNode* p; 
	p = T; 
	while (!S.empty() || p)
	{
		if (p)
		{
			S.push(p);
			p = p->m_pLeft; 
		}
		else
		{
			p = S.top();
			S.pop(); 
			cout << p->m_nValue << " "; 
			p = p->m_pRight;
		}

	}
}

//非递归后序遍历 
void NoLastRecursiveVist(BinaryTreeNode * T)
{
	stack<BinaryTreeNode *> S; 
	BinaryTreeNode * p; 
	BinaryTreeNode *pre = NULL; 
	p = T;
	while (!S.empty() || p)
	{
		while (p)
		{
			S.push(p);
			p = p->m_pLeft;
 		}
		p = S.top(); 
		if (p->m_pRight == NULL || p->m_pRight == pre) //如果没有右儿子,或者右子树全部访问完毕,则输出此根节点
		{
			cout << p->m_nValue << " ";
			pre = p; 
			p = NULL;
			S.pop();
		}
		else
			p = p->m_pRight; 
	}
}


int main()
{ 
	int preOrder[8] = {1,2,4,7,3,5,6,8}; 
	int inOrder[8] = { 4, 7, 2, 1, 5, 3, 8, 6 };
	BinaryTreeNode * node = Construct(preOrder, inOrder,8);  

	cout << "先序遍历" << endl;
     PreOrderVisit(node);
	cout << endl;
	
	cout << "非递归先序遍历二叉树" << endl;
	NoPreRecursiveVist(node);
	cout << endl;
	
	cout << "中序遍历" << endl;
	InOrderVisit(node);
	cout << endl;

	cout << "非递归中序遍历二叉树" << endl;
	NoInRecursiveVist(node);
	cout << endl;

	cout << "后序遍历" << endl;
	LastOrderVisit(node);
	cout << endl;

	cout << "非递归后序遍历二叉树" << endl;
	NoLastRecursiveVist(node);
	cout << endl;

	cout << "层序遍历" << endl;
	LevelOrderVisit(node);
	cout << endl;
	
	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值