二叉树的递归非递归遍历

二叉树定义结构:

struct BtNode{
	int data;
	BtNode * lchild;
	BtNode * rchild;
};

二叉树有三种遍历,前序遍历,中序遍历,后序遍历

前序遍历的顺序是对每一棵树(子树),先访问根节点,然后访问左子树,然后访问右子树

中序遍历的顺序是对每一棵树,先访问左子树,再访问根节点,再访问右子树;

后序遍历的顺序是对每一棵树,先访问左子树,再访问右子树,在访问根节点

按照这个思路,递归的写法非常直观,而非递归的写法都要借助于栈来完成

前序遍历:

递归写法

void preOrder1(BtNode * T)
{
	if(T)
	{
		cout<<T->data<<" ";
		preOrder1(T->lchild);
		preOrder1(T->rchild);
	}
}

非递归写法

void preOrder2(BtNode *T)
{
	//根节点入栈 
	stack<BtNode*>st;
	BtNode * p = T;
	st.push(p);
	while(!st.empty())
	{
		//先访问根节点 
		p = st.top();st.pop();
		cout<<p->data<<" ";
		//右节点先入栈,再入栈左节点,这样访问的时候会先弹出左节点 
		if(p->rchild!=NULL)
		{
			st.push(p->rchild); p = p->rchild;
		}
		if(p->lchild !=NULL)
		{
			st.push(p->lchild);p= p->lchild;
		}
	}
}

中序遍历:

递归写法

void inOrder1(BtNode * T)
{
	if(T)
	{
		inOrder1(T->lchild);
		cout<<T->data<<" ";
		inOrder1(T->rchild);
	}
 }

非递归写法

void inOrder2(BtNode *T)
{
	stack<BtNide*>st;
	BtNode * p = T;
	while(!st.empty() || p)
	{
		//每一次先找到最左边的那个节点 
		while(p)
		{
			st.push(p);
			p = p -> lchild;
		}
		if(!st.empty())
		{
			p = st.top();
			st.pop();
			cout<<p->data<<" ";
			//这里如果有右节点就访问,没有为空就直接访问父节点的那个根节点了 
			p = p -> rchild;
		}
	}
}

后续遍历:

递归写法

void postOrder1(BtNode * T)
{
	if(T) {
	postOrder1(T->lchild);
	postOrder1(T->rchild);
	cout<<T->data<<" ";	
	}
}

非递归写法

void postOrder2(BtNode *T)
{
	stack<BtNode *> st;
	//plastVisit记录上次访问哪个节点,因为只有右节点也被访问过后才访问当前节点 
	BtNode * pcur,plastVisit;
	pcur = T; plastVisit = NULL;
	//还是先从最左边的节点开始 
	while(pcur)
	{
		st.push(pcur);
		pcur = pcur->lchild;
	}
	while(!st.empty())
	{
		pcur = st.top();st.pop();
		//当前在最左边,没有右节点或者右节点已经被访问过,就访问当前节点(子树的根节点) 
		if(pcur->rchild == NULL || pcur->rchild == plastVisit)
		{
			cout<<pcur->data<<" ";
			plastVisit = pcur;
		}
		//右节点没有访问过 ,那当前根节点进栈,右节点进栈,然后进一步找右边子树最左边的节点 
		else{
			st.push(pcur);
			pcur = pcur -> rchild; 
			while(pcur)
			{
				st.push(pcur);
				pcur = pcur->lchild; 
			} 
		}
	}
}

猜你喜欢

转载自blog.csdn.net/BeforeEasy/article/details/85045979