目录
前言
本篇文章主要介绍非递归后序遍历的算法,并且在这个算法的基础之上解决问题
1、求树的深度
2、打印值为x的节点的所有祖先
3、求两个节点的最近公共祖先节点
4、输出从每个叶子节点到根节点的逆路径
这个算法具有一个良好的性质即当访问到某节点时,栈中存放的是整个节点的祖先节点
//非递归后序遍历
void PostOrder(BiTree T){
if(T!=NULL){
BiTree St[105];
int top=-1;
BiTree p=T;
BiTree r=NULL;
while(p!=NULL||top!=-1){
if(p!=NULL){
St[++top]=p;
p=p->lchild;
}
else{
p=St[top];
if(p->rchild!=NULL&&p->rchild!=r){
p=p->rchild;
}else{
p=St[top--];
cout<<p->data<<' ';
r=p;
p=NULL;
}
}
}
}
}
-
求树的深度
树的深度为后序遍历过程中栈中元素个数的最大值
//非递归后序遍历求二叉树高度
int Depth2(BiTree T){
if(T!=NULL){
stack<BiTree> St;
BiTree p=T;
BiTree r=NULL;
int height=0;
while(p!=NULL||!St.empty()){
if(p!=NULL){
St.push(p);
height=max(height,(int)St.size());
p=p->lchild;
}
else{
p=St.top();
if(p->rchild!=NULL&&p->rchild!=r){
p=p->rchild;
}else{
p=St.top();
St.pop();
r=p;
p=NULL;
}
}
}
return height;
}
}
主函数
int main(){
system("chcp 65001");
BiTree T;
CreatBiTree(T);
cout<<"二叉树的最大深度为:"<<endl;
cout<<Depth2(T)<<endl;
return 0;
}
运行结果如下图所示:
上图中建的树如下图所示:
-
打印值为x的节点的所有祖先
访问到节点值为x的节点时打印栈中元素即可
//打印值为x的结点的所有祖先
void AncestorNode(BiTree T,char x){
if(T!=NULL){
BiTree St[105];
int top=-1;
int i;
BiTree p=T;
BiTree r=NULL;
while(p!=NULL||top!=-1){
if(p!=NULL){
St[++top]=p;
p=p->lchild;
}
else{
p=St[top];
if(p->rchild!=NULL&&p->rchild!=r){
p=p->rchild;
}else{
if(p->data==x){
for(i=0;i<top;i++){
cout<<St[i]->data<<" ";
}
}
p=St[top--];
r=p;
p=NULL;
}
}
}
}
}
主函数
int main(){
system("chcp 65001");
BiTree T;
CreatBiTree(T);
char x;
cin>>x;
cout<<x<<"节点的祖先:"<<endl;
AncestorNode(T,x);
return 0;
}
运行结果如下图所示
-
求节点t,s最近公共祖先节点
访问到节点t时将栈中元素即节点t的祖先保存到一个数组anor中,访问到节点s时将栈中元素即节点s的祖先与数组anor中元素比较得到最近公共祖先
//求最近公共祖先节点
void ancestor(BiTree T,char t,char s){
if(T!=NULL){
BiTree St[105];
char anor[105];
int top=-1;
int i;
BiTree p=T;
BiTree r=NULL;
while(p!=NULL||top!=-1){
if(p!=NULL){
St[++top]=p;
p=p->lchild;
}
else{
p=St[top];
if(p->rchild!=NULL&&p->rchild!=r){
p=p->rchild;
}else{
if(p->data==t){
for(i=0;i<top;i++){
anor[i]=St[i]->data;
}
p=St[top--];
r=p;
p=NULL;
}else if(p->data==s){
i=0;
while(anor[i]==St[i]->data){
i++;
}
cout<<t<<"和"<<s<<"的最近公共祖先为:"<<anor[i-1]<<endl;
break;
}else{
p=St[top--];
r=p;
p=NULL;
}
}
}
}
}
}
主函数
int main(){
system("chcp 65001");
BiTree T;
CreatBiTree(T);
char t,s;
cout<<"请输入两个节点:"<<endl;
cin>>t>>s;
ancestor(T,t,s);
cout<<endl;
return 0;
}
运行结果如下图所示
-
输出从每个叶子节点到根节点的逆路径
后序遍历访问到叶子节点时倒序输出栈中元素即倒序输出该叶子结点的祖先节点,这些节点构成了叶子结点到根节点的逆路径
//输出从每个叶子节点到根节点的逆路径
void AllPath(BiTree T){
if(T!=NULL){
BiTree St[105];
int top=-1;
int i;
BiTree p=T;
BiTree r=NULL;
while(p!=NULL||top!=-1){
if(p!=NULL){
St[++top]=p;
p=p->lchild;
}
else{
p=St[top];
if(p->rchild!=NULL&&p->rchild!=r){
p=p->rchild;
}else{
if(p->lchild==NULL&&p->rchild==NULL){
cout<<p->data<<"到根节点的路径"<<p->data;
for(i=top-1;i>=0;i--){
cout<<St[i]->data;
}
cout<<endl;
}
p=St[top--];
r=p;
p=NULL;
}
}
}
}
}
主函数
int main(){
system("chcp 65001");
BiTree T;
CreatBiTree(T);
AllPath(T);
return 0;
}
运行结果如下图所示: