前中后序遍历二叉树

前序遍历二叉树

算法描述:先访问这棵树,如果树为空,就跳出。如果树不为空,然后再访问这棵树的根节点,然后访问这棵树的左子树,左子树访问完之后就访问这棵树的右子树。
我们用到栈这个数据结构,遍历以下这个二叉树:
前中后序遍历二叉树_第1张图片

我们访问根节点A,将它入栈,然后再出栈,然后我们再入这A的右孩子G,再入左孩子B,然后将B出栈,再入B的右孩子D,然后入它的左孩子C,C的左右孩子为空,就将C打印然后再将B打印,接着先入F再入E,将E出栈后再将F出栈,然后再出G,再入H…依次出栈。
代码实现:

#include
using namespace std;
void NicePreOrder(struct BtNode *ptr)
{
	if(ptr == NULL) return ;
	stack<struct BtNode *> st;
	st.push(ptr);
	while(!st.empty())
	{
		ptr = st.top();
		st.pop();	
		cout<<ptr->data<<" ";
		if(ptr->rightchild !=NULL)
		{
			st.push(ptr->rightchild);
		}
		if(ptr->leftchild != NULL)
		{
			st.push(ptr->leftchild);
		}
	}
	cout<<endl;
}

中序遍历二叉树

算法描述:先访问这棵树,如果树为空,就跳出。如果树不为空,然后再访问这棵树的左孩子,如果左孩子为空,就退回到访问这棵树的父节点,然后再访问这棵树的右结点,如果右结点为空就回退到这棵树的父节点,然后接着向上后退。直到它的左右孩子都为空时就打印这个结点。
我们就用到栈这个数据结构。比如一颗二叉树如下所示:
前中后序遍历二叉树_第2张图片

我们先将这棵树的A结点入栈,然后访问它的左孩子B结点,然后将B结点入栈,接着访问B的左孩子C,将C入栈,访问C的左孩子,发现C的左孩子为空,我们就将C出栈,然后访问C的右孩子,发现C的右孩子为空,就退回到B,这样B的左子树就访问完了,然后将B出栈。接着去访问B的右孩子D,将D入栈,然后再去访问D的左孩子…依次类推,直到所有结点都访问完。
代码实现:

void NicePastOrder(struct BtNode *ptr)
{
	if(NULL == ptr) return ;
	stack<struct BtNode*> st;
	while(!st.empty() || ptr != NULL)
	{
		while(ptr != NULL)
		{
			st.push(ptr);
			ptr = ptr->leftchild;
		}
		ptr = st.top();
		st.pop();
		cout<<ptr->data<<" ";
		ptr = ptr->rightchild;
	}
	cout << endl;
}

后序遍历二叉树

算法描述:先访问这棵树,如果树为空,就跳出。如果树不为空,然后再访问这棵树的左孩子,然后再访问这棵树的右孩子,如果左孩子为空,此时不退回到父节点,而是去访问这棵树的右结点,如果右结点为空就回退到这棵树的父节点,然后接着向上后退。直到它的左右孩子都为空时就打印这个结点。
我们就用到栈这个数据结构,我们遍历一颗二叉树如下图所示:
前中后序遍历二叉树_第3张图片

我们先将这棵树的A结点入栈,然后访问它的左孩子B结点,然后将B结点入栈,接着访问B的左孩子C,将C入栈,访问C的左孩子,发现C的左孩子为空,然后访问C的右孩子,发现C的右孩子为空,此时将C出栈,然后去访问B的右孩子D,将D入栈,然后再去访问D的左孩子E,将E入栈,然后去访问E的左右孩子,将E的左右孩子访问完后,将E出栈,然后访问D的右孩子F,将F入栈,访问F的左右孩子,当将F的左右孩子都访问完之后将F出栈,此时B的左右孩子已经访问完了,然后将B出栈,然后去访问A的右孩子,直到A的右孩子访问完之后,再将A出栈…,直到所有结点都访问完。
但是,难点就在于如何判断这些结点的右子树是被访问过的。我们定义一个tag,来标记左右孩子被访问过的结点。如上图的二叉树,定义一个ptr来访问这棵树,当访问C时,发现C的左右结点为空,我们就将tag指向C,然后ptr接着访问,直到访问到E时,发现E的左右孩子都为空,接着讲tag指向E…依次类推。
代码实现:

void NiceLastOrder(struct BtNode *ptr)
{
	if(NULL == ptr) return ;
	stack<struct BtNode *> st;
	struct BtNode* tag = NULL;
	while(!st.empty() || ptr != NULL)
	{
		while(ptr != NULL)
		{
			st.push(ptr);
			ptr = ptr->leftchild;
		}
		ptr = st.top();
		st.pop();
		if(ptr->rightchild == NULL || ptr->rightchild == tag)
		{
			cout << ptr->data << " ";
			tag = ptr;
			ptr = NULL;
		}
		else
		{
			st.push(ptr);
			ptr = ptr->rightchild;
		}
	}
	cout << endl;
}

你可能感兴趣的:(数据结构,面试题)