二叉树的恢复

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

先序遍历:根、左、右

中序遍历:左、根、右

后序遍历:左、右、根

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

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

你可能感兴趣的:(数据结构,算法,数据结构,c++)