int maxSize = 1000;
//这个是重点
//后序遍历非递归,tag标记实现
void postOrderTraverse_non_recursion3(Tree T)
{
int top = 0;
int tag[maxSize];//tag标记该结点右分支是否被访问过,只有当该节点的右分支访问过了才能访问根节点
Tree p = T;
Tree S[maxSize];//S作为栈
while(p!=NULL||top>0)
{
while(p!=NULL)//沿左分支遍历
{
S[++top] = p;//入栈
tag[top] = 0;
p = p->lchild;
}//end while
while(top>0&&tag[top] == 1)//该节点的右分支访问过了,则可以访问该节点
{
Visit(S[top]);
top--;
}
if(top>0)//沿右分支遍历
{
tag[top] = 1;//标记该右分支已遍历
p = S[top]->rchild;
}
}//end while
}//end postOrderTraverse_non_recursion3
//基于后序非递归(tag标记)的题目
//在二叉树中查找值为x的结点,打印x结点的祖先
/*
基本思想,后序遍历找到该节点,栈中存放的就是该节点的到根节点的路径
tag[]标记实现
*/
void serch(Tree T,int x)
{
int top =0;
int tag[maxSize];//基于后序非递归(tag标记)的题目
//求 p,q最近的公共结点
Tree p = T;
Tree S[maxSize];
while(p!=NULL&&top>0)
{
while(p!=NULL)//沿左分支寻找
{
S[++top] = p;
tag[top] = 0;
p = p->lchild;
}
while(top>0&&tag[top] == 1)//右分支访问过了
{
if(p->data == x)//找到该节点,则栈中的结点就是其祖先
for(int i=1; i<=top; i++)
Visit(S[i]);
top--;//访问则出栈
}
if(top>0)//沿右分支寻找
{
tag[top] = 1;
p = S[top]->rchild;
}
}//end while
}//end search
//基于后序非递归(tag标记)的题目
//求 p,q最近的公共结点
/*
基本思想:
1.后序遍历到p时则栈内的结点都是p的祖先
2.将其复制到另外一个栈中继续遍历到q
3.比较2栈的结点,第一个相同的结点即为最近公共结点
*/
Tree findAncestor(Tree T,Tree p,Tree q)
{
int top1,top2;
int tag1[maxSize],tag2[maxSize];
Tree S1[maxSize],S2[maxSize];
Tree pT =T;
while(pT!=NULL||top1>0)
{
while(pT!=NULL)
{
S1[++top1] = pT;
tag1[top1] = 0;
pT = pT->lchild;
}
while(top1>0&&tag1[top1] == 1)//右分支访问过了
{
if(S1[top1] == p) //将S1复制给S2
{
for(int i=1; i<=top1; i++)
S2[i] = S1[i];
top2 = top1;
}
if(S1[top1] == q)//找到q,则对比2栈内的结点,第一个相同的结点就是最近公共结点
{
for(int i=top1;i>0;i--)
for(int j=top2;j>0;j--)
if(S1[i] == S2[j])
return S1[i];//找到公共结点
}
top1--;//访问出栈
}//end while
if(top1>0)
{
tag1[top1] = 1;
pT = S1[top1]->rchild;
}
}//end while
return NULL;
}
//输出最长路径上的结点(考过多年)(重点)
/*
基本思想:
后序非递归(tag标记实现方法)
1.当该=遍历到该结点没有左右孩子结点的时候,记录当前路径长度并于最长路径长度比较
2.最后输出最长路径
*/
void longPath(Tree T)
{
int top =0;
int longSet = 0;//初始化最长路径长度
int tag[maxSize];
Tree p = T,S[maxSize],Temp[maxSize];//S为存放最长路径上的结点,Temp为临时存放
while(p!=NULL||top>0)
{
while(p!=NULL)//沿着左分支寻找
{
S[++top] = p;
tag[top] = 0;
p = p->lchild;
}//end while
while(top>0&&tag[top] == 1)
{
//当该结点没有左右孩子结点的时候记录路径长度,并于最长路径长度进行比较来更新最长路径长度
if(S[top]->lchild == NULL &&S[top]->rchild == NULL)
if(top>longSet)//更新最长路径
{
for(int i=1;i<=top;i++)
Temp[i] = S[i];
longSet =top;
}
top--;
}//end while
if(top>0)
{
tag[top] = 1;
p = S[top]->rchild;
}
}//end while
}//end longPath