二叉树的遍历你会几种方法

                                                       二叉树的遍历

  一棵二叉树的基本操纵,在这片博客里有记录:点击打开链接

  一棵二叉树的多种建树方法也在这篇博客中:点击打开链接

  一颗线索化的树操作在:点击打开链接

   今天这篇博客就是教你多种遍历的方法。咋们平时都知道一棵树的基本遍历就是先序,中序,后序。那么你也许会直接想起递归的实现遍历,那么你到底还会不会其他的方法。

   今天这里教你三种方法。

第一种:递归的二叉树遍历。

第二种:用栈实现二叉树的遍历

第三种:栈加计数来实现二叉树的遍历

第四种:是线索化遍历

注:附件其他的遍历方式;

 第一种的三种遍历方式

//先序遍历
void Pretra(BtNode *p)
{
	if(p != NULL)
	{
		cout<<p->data<<" ";
	    Pretra(p->leftchild);
	    Pretra(p->rightchild);
	}
}
//中序遍历
void Midtra(BtNode *p)
{
	if(p != NULL)
	{
		Midtra(p->leftchild);
		cout<<p->data<<" ";
		Midtra(p->rightchild);
	}
}
//后序遍历
void Lasttra(BtNode *p)
{
	if(p != NULL)
	{
		Lasttra(p->leftchild);
		Lasttra(p->rightchild);
		cout<<p->data<<" ";
	}
}

第二种:

/先序遍历
void NicePreOrder(BtNode *p)
{
	 BtNode *s = NULL;
	 stack<BtNode* > st;
	 st.push(p);
	 while(!st.empty())
	 {
		 BtNode *node = st.top();st.pop();
		 cout<<node->data<<" ";
		 if( node->rightchild != NULL)
		 {
			 st.push(node->rightchild);
			 if(node->leftchild != NULL)
			 {
                 st.push(node->leftchild);
			 }
		 }
	 }
	 cout<<endl;
}
//中序遍历
void NiceMiOrder(BtNode *p)
{
	BtNode *s = NULL;
	stack<BtNode* > st;
	while(p != NULL || !st.empty())
	{
		while(p != NULL)
		{
			st.push(p);
			p = p->leftchild;
			
		}
		BtNode *node = st.top();st.pop();
	    cout<<node->data<<" ";
	    p = node->rightchild;
	}
	cout<<endl;
}
//后序遍历
void NiceLaOrder(BtNode *p)
{
	BtNode *s = NULL;
	stack<BtNode *> st;
	BtNode *tag = NULL;
	while(p != NULL || !st.empty())
	{
		while(p != NULL)
		{
			st.push(p);
			p = p->leftchild;
		}
		BtNode *node = st.top();st.pop();
		if(node->rightchild == NULL || node->rightchild == tag)
		{
			cout<<node->data<<" ";
			tag = node;
			node = NULL;
		}
		else
		{
			st.push(node);
			p = node->rightchild;
		}
		
	}
	cout<<endl;
}

第三种:技术遍历


看着上面的图,我来先介绍一下。每一个节点入栈的时候,默认计数都是0。每出一次栈,都会计数加一。那么那么你的第一次计数为1的时候,我们开始访问他的左子树,当计数为2的时候,我们开始访问他的右子树。


struct SkNode
{
	BtNode *pnode;
	int popnum;
	SkNode(BtNode *p=NULL,int num=0):pnode(p),popnum(num){}
};

//先序遍历
void NicePreOrder1(BtNode *p)
{
	BtNode *s = NULL;
	stack<SkNode > st;
	st.push(SkNode(p));
	while(!st.empty())
	{
        SkNode node = st.top();st.pop();
		if(++node.popnum == 1)
		{
			cout<<node.pnode->data<<" ";
		   if( node.pnode->rightchild != NULL)
		   {
				st.push(node); 
		   }
		   if( node.pnode->leftchild != NULL)
		   {
			   st.push(SkNode(node.pnode->leftchild));
		   }
		}
		else if(node.popnum == 2)
		{
            st.push(SkNode(node.pnode->rightchild));
		}
	}
	cout<<endl;
}
//中序遍历
void NiceMiOrder1(BtNode *p)
{
	BtNode *s = NULL;
	stack<SkNode> st;
	st.push(SkNode(p));
	while(!st.empty())
	{
         SkNode node = st.top();st.pop();
		 if(++ node.popnum == 2)
		 {
			 cout<<node.pnode->data<<" ";
			 if(node.pnode->rightchild != NULL)
			 {
				 st.push(SkNode(node.pnode->rightchild));
			 }
		 }
		 else if(node.popnum == 1)
		 {
			 st.push(node);
			 if(node.pnode->leftchild != NULL)
				 st.push(SkNode(node.pnode->leftchild));
		 }
	}
	cout<<endl;
}
//后序遍历
void NiceLaOrder1(BtNode *p)
{
	BtNode *s = NULL;
	stack<SkNode> st;
	st.push(SkNode(p));
	while(!st.empty())
	{
		SkNode node = st.top();st.pop();
		if(++node.popnum == 3)
		{
			cout<<node.pnode->data<<" ";
		}
		else 
		{
			st.push(node);
			if(node.popnum == 1 && node.pnode->leftchild != NULL)
			{
				 st.push(SkNode(node.pnode->leftchild));
			}
			else if(node.popnum == 2 && node.pnode->rightchild != NULL)
			{
				st.push(SkNode(node.pnode->rightchild));
			}
			
		}
	}
	cout<<endl;
}
最后介绍一下,逐层访问每一个节点;

//层次打印这个二叉树
//1.在层次打印的时候,要先进先出。那么就用容器queue
void NiceleveDrder(BtNode *p)
{
	if(p == NULL) return ;
	queue<BtNode *> qu;
	qu.push(p);
	while(!qu.empty())
	{
		BtNode *node = qu.front();qu.pop();
		cout<<node->data<<" ";
		if(node->leftchild != NULL)
			qu.push(node->leftchild);
		if(node->rightchild != NULL)
			qu.push(node->rightchild);
	}
	cout<<endl;
}
//2.可以调用打印第k层的函数来逐层打印
void NiceleveDrder1(BtNode *p)
{
	int n = Depth(p);
	for(int i = 1;i <= n;++i)
	{
         print_kleve_Item(p,i);
	}
	cout<<endl;
}

第四种:
//中序遍历一颗线索二叉树

BiThNode *First(BiThNode *p)
{
	while(p != NULL && p->ltag != THREAD)
	{
		p = p->leftchild; 
	}
	return p;
}
BiThNode *Next(BiThNode *p)
{
	if(p == NULL) return NULL;
	if(p->rtag == LINK)
	{
		BiThNode *ptr = First(p->rightchild);
		return ptr;
	}
	else
	{
		return p->rightchild;
	}
}
void ThreadMiinder(BiThNode *p)
{
	for(BiThNode *s = First(p);s != NULL;s = Next(s))
	{
		cout<<s->data<<" ";
	}
	cout<<endl;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值