二叉树的恢复

二叉数有先序、中序、后序遍历

先序遍历:根、左、右

中序遍历:左、根、右

后序遍历:左、右、根

要恢复二叉数只能用先序遍历和中序遍历、中序遍历和后序遍历的结果进行恢复。

class Node
{
public:
	Node():m_left(nullptr),m_right(nullptr){}
	Node(char v):m_value(v),m_left(nullptr),m_right(nullptr){}
	char m_value;
	Node* m_left;
	Node* m_right;
};
class Tree
{
public:
	Tree() :m_root(nullptr){}
	void postOrder();
	void PreOrder();
	void fun(Node*&root,const char* PreOrder, const char* InOrder, int n);
	void fun1(Node*& root, const char* InOrder, const char* postOrder, int n);
	Node* m_root;
};
void Tree::PreOrder()
{
	Node* p = m_root;
	stack<Node*> q;
	if (p != nullptr)
	{
		q.push(p);
		while (!q.empty())
		{
			Node* front = nullptr;
			front = q.top();
			cout << front->m_value << " ";
			q.pop();
			if (front->m_right != nullptr)//陷入右孩子为了将左边访问完,能够再找到右孩子
			{
				q.push(front->m_right);
			}
			if (front->m_left != nullptr)
			{
				q.push(front->m_left);
			}
		}
	}
}
void Tree::postOrder()
{
	Node* pre = nullptr;
	stack<Node*> q;
	Node* top = nullptr;
	if (m_root != nullptr)
	{
		q.push(m_root);
		while (!q.empty())
		{
			top = q.top();
			if ((top->m_left == nullptr && top->m_right == nullptr) || ( pre != nullptr&&top->m_left==pre || pre != nullptr && top->m_right == pre))
			{
				cout << top->m_value << " ";
				q.pop();
				pre = top;
			}
			else
			{
				if (top->m_right)
				{
					q.push(top->m_right);
				}
				if (top->m_left)
				{
					q.push(top->m_left);
				}
			}
		}
	}
}
//先序、中序进行恢复树
void Tree::fun(Node*&root,const char* PreOrder, const char* InOrder, int n)
{
	if (n == 0)//结点为0时是空树
	{
		root = nullptr;
	}
	else
	{
		int k = 0;
		while (PreOrder[0] != InOrder[k])//找到根节点,先序遍历中第一个结点是根节点
		{
			k++;//k的值是左子树有多少结点的个数
		}
		root = new Node(PreOrder[0]);//建立新的根节点
		fun(root->m_left, PreOrder + 1, InOrder, k);//递归左子树
		fun(root->m_right, PreOrder + k + 1, InOrder + k + 1, n - k - 1);//递归右子树
	}
}
//中序、后序进行恢复树
void Tree::fun1(Node*& root, const char* InOrder, const char* postOrder,int n)
{
	if (n == 0)//结点为0时是空树
	{
		root = nullptr;
	}
	else
	{
		int k = 0;
		while (InOrder[k] != postOrder[n - 1])//找到根节点,先序遍历中第一个结点是根节点
		{
			k++;//k的值是左子树有多少结点的个数
		}
		root = new Node(postOrder[n - 1]);//建立新的根节点
		fun1(root->m_left, InOrder, postOrder, k);//递归左子树
		fun1(root->m_right, InOrder + k + 1, postOrder + k, n - k - 1);//递归右子树
	}
}
void main()
{
	Tree t;
	t.m_root = nullptr;
	const char* PreOrder = "ABDEGHCF";
	const char* InOrder = "DBGEHACF";
	const char* postOrder = "DGHEBFCA";
	int n = strlen(PreOrder);
	cout << "用先序、中序恢复树" << endl;
	t.fun(t.m_root, PreOrder, InOrder, n);
	cout << "用后序进行输出:";
	t.postOrder();
	cout << endl;
	cout << "用中序、后序恢复树" << endl;
	t.fun1(t.m_root, InOrder, postOrder, n);
	cout << "用先序进行输出:";
	t.PreOrder();
	cout << endl;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秉麟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值