后序非递归遍历二叉树的应用

1.打印值为x的结点的所有祖先

栈从0开始,top初始值-1

#include "stdafx.h"
#include<iostream>
using namespace std;
typedef struct BTreeNode
{
	int data;
	struct BTreeNode *lchild,*rchild;
}BTree;
typedef struct stacknode
{
	BTree *node;
	int tag;//tag为0表示结点左子女已经访问,为1表示右子女已经访问
}stack;
int _tmain(int argc, _TCHAR* argv[])
{
	return 0;
}
void Search(BTree *b,int x)
{
	stack s[100];
	int top=-1;
	stack temp;//暂存结点信息
	while(b||top>-1)
	{
		while(b)
		{
			temp.node=b;
			temp.tag=0;//左结点已访问
			s[++top]=temp;
			b=b->lchild;
		}

		//以下为功能代码
		if(b->data==x)
		{
			printf("所查结点的所有祖先为:\n");
			for(int i=0;i<=top;i++)
			{
				cout<<s[i].node->data;
			}
			exit(0);//输出完成后退出程序
		}
		while(top&&s[top].tag==1){ //表示右子树访问完毕,所以访问根节点  
			//b = s[top --].node;
			//cout << b->val << ' ';
			/*之前是写这两行,但是会导致最后top为0时,p非空,所以会不断循环最外层的while(p||top)
			如果要写这两行而不写下面那句的话,要采用do{}while(top);*/
			cout << s[top --].node->data<< ' ';
		}
		if(top!=-1)
		{
			s[top].tag= 1; //右结点已访问           
			b = s[top].node;           
			b = b->rchild;
		}
	}
}

 2.p,q最近公共祖先

#include "stdafx.h"
#include<iostream>
using namespace std;
typedef struct BTreeNode
{
	int data;
	struct BTreeNode *lchild,*rchild;
}BTree;
typedef struct stacknode
{
	BTree *node;
	int tag;//tag为0表示结点左子女已经访问,为1表示右子女已经访问
}stack;
int _tmain(int argc, _TCHAR* argv[])
{
	return 0;
}
BTree *Ancestor(BTree *b,BTree *p,BTree *q,BTree *r)
{
	stack s[100],s1[100];//辅助栈
	int top=-1,top1=-1;
	stack temp;//暂存结点信息
	while(b||top>-1)
	{
		while(b)
		{
			temp.node=b;
			temp.tag=0;//左结点已访问
			s[++top]=temp;
			b=b->lchild;
		}

		//以下为功能代码
		if(b==p)//不失一般性,设p在q的左边,所以p必定先于q被访问,把栈中已有元素复制到另一栈中去
		{
			for(int i=0;i<=top;i++)
			{
				s1[i]=s[i];
			}
			top1=top;
		}
		if(b==q)//找到q
		{
			for(int i=top;i>=0;i--)//将栈中元素的树结点到s1中去匹配
			{
				BTree *pp=s[i].node;
				for(int j=top1;j>=0;j--)
				{
					if(s1[j].node==pp)
						return pp;
				}
			}
		}
		while(top&&s[top].tag==1){ //表示右子树访问完毕,所以访问根节点  
			//b = s[top --].node;
			//cout << b->val << ' ';
			/*之前是写这两行,但是会导致最后top为0时,p非空,所以会不断循环最外层的while(p||top)
			如果要写这两行而不写下面那句的话,要采用do{}while(top);*/
			cout << s[top --].node->data<< ' ';
		}
		if(top!=-1)
		{
			s[top].tag= 1; //右结点已访问           
			b = s[top].node;           
			b = b->rchild;
		}
	}
}

 3.到叶结点的路径

#include "stdafx.h"
#include<iostream>
using namespace std;
typedef struct BTreeNode
{
	int data;
	struct BTreeNode *lchild,*rchild;
}BTree;
typedef struct stacknode
{
	BTree *node;
	int tag;//tag为0表示结点左子女已经访问,为1表示右子女已经访问
}stack;
int _tmain(int argc, _TCHAR* argv[])
{
	return 0;
}
BTree *Ancestor(BTree *b,BTree *p,BTree *q,BTree *r)
{
	stack s[100],s1[100];//辅助栈
	int top=-1,top1=-1;
	stack temp;//暂存结点信息
	while(b||top>-1)
	{
		while(b)
		{
			temp.node=b;
			temp.tag=0;//左结点已访问
			s[++top]=temp;
			b=b->lchild;
		}

		//以下为功能代码
		if(b->lchild!=NULL&&b->rchild!=NULL)
		{
			for(int i=0;i<=top;i++)
			{
				cout<<s[i].node->data;
			}
			cout<<b->data;
		}
		while(top&&s[top].tag==1){ //表示右子树访问完毕,所以访问根节点  
			//b = s[top --].node;
			//cout << b->val << ' ';
			/*之前是写这两行,但是会导致最后top为0时,p非空,所以会不断循环最外层的while(p||top)
			如果要写这两行而不写下面那句的话,要采用do{}while(top);*/
			cout << s[top --].node->data<< ' ';
		}
		if(top!=-1)
		{
			s[top].tag= 1; //右结点已访问           
			b = s[top].node;           
			b = b->rchild;
		}
	}
}

 4.根节点到叶结点最长路径

#include "stdafx.h"
#include<iostream>
using namespace std;
typedef struct BTreeNode
{
	int data;
	struct BTreeNode *lchild,*rchild;
}BTree;
typedef struct stacknode
{
	BTree *node;
	int tag;//tag为0表示结点左子女已经访问,为1表示右子女已经访问
}stack;
int _tmain(int argc, _TCHAR* argv[])
{
	return 0;
}
BTree *Ancestor(BTree *b,BTree *p,BTree *q,BTree *r)
{
	stack s[100],l[100];//辅助栈
	int top=-1,top1=-1,longest=0;
	stack temp;//暂存结点信息
	while(b||top>-1)
	{
		while(b)
		{
			temp.node=b;
			temp.tag=0;//左结点已访问
			s[++top]=temp;
			b=b->lchild;
		}

		//以下为功能代码
		if(s[top].tag==1)//右结点已访问  
		{
			if(s[top].node->lchild&&s[top].node->rchild)
			{
				if(top>longest)
				{
					for(int i=0;i<=top;i++)
					{
						l[i]=s[i];//保存栈中结点
					}
					longest=top;
					top--;//出栈
				}
			}
		}
		while(top&&s[top].tag==1){ //表示右子树访问完毕,所以访问根节点  
			//b = s[top --].node;
			//cout << b->val << ' ';
			/*之前是写这两行,但是会导致最后top为0时,p非空,所以会不断循环最外层的while(p||top)
			如果要写这两行而不写下面那句的话,要采用do{}while(top);*/
			cout << s[top --].node->data<< ' ';
		}
		if(top!=-1)
		{
			s[top].tag= 1; //右结点已访问           
			b = s[top].node;           
			b = b->rchild;
		}
	}
}







 

posted @ 2012-08-10 22:51  代码改变未来  阅读(293)  评论(0编辑  收藏  举报