二叉树中输出节点的祖先以及找最近公共祖先

问题1

给定一颗二叉树,给定某个结点X的值,要求打印出该结点的祖先。

思路

想想上一篇中有讲到后序遍历的非递归算法,其中栈里面保存的正是从根结点到当前结点的一条路径。如果当前结点就是要找的结点X的话,那么栈里面保存的就是该结点的所有祖先,依次输出即可。如果当前结点不是要找的结点X,如果标记位为1则继续遍历,否足则对该结点进行空遍历(即将该结点弹出栈)

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <malloc.h>
#include <stack>
#include <queue>
#include <bits/stdc++.h>

using namespace std;


typedef struct BiTNode{
    char data;
    struct BiTNode *left,*right;
}BiTNode,*BiTree;


BiTree build()
{
    char c;
    BiTree st = nullptr;
    c=getchar();
    if(c!='#')

    {

        st = new BiTNode();
        st ->data = c;//已知为先序遍历,先填充根节点
        st ->left = build();//递归形式填充左分支
        st ->right = build();//递归形式填充左分支
    }
    return st;
}

void visit(BiTNode *x)
{

    cout<<x->data<<' ';
}

//后序非递归
void backVisitStack(BiTree root,char x)
{

    BiTNode* p = root;
    stack<pair<BiTNode*,int>>st;

    while(p != nullptr || !st.empty()){
        while(p!=nullptr && p->data != x){
            st.push(make_pair(p,1));
            p = p->left;
        }
        if(p != nullptr && p->data == x){
            while(!st.empty()){
                visit(st.top().first);
                st.pop();
            }
            return ;
        }
        while(!st.empty() && st.top().second == 2) st.pop();
        if(!st.empty()){
            st.top().second = 2;
            p = st.top().first->right;
        }
    }
    cout << endl;
}

/* 树的结构
        A
      /   \
     B     C
    / \   /
   D   E  F
  /     \
 G       H
*/



//先序序列 ABDG###E#H##CF###

// 根据先序 建树


int main()
{

    BiTree bt;
    bt = build();

    char x = 'H';
    backVisitStack(bt,x);

    return 0;
}

问题2

给定一棵二叉树,以及两个结点的值,找出这两个结点的最近公共祖先

思路

还是利用非递归的后序遍历,不过可以假设x结点在y结点的左边,当遍历到x结点时,利用一个辅助栈将其祖先保存下来,继续遍历到y,然后从栈顶开始找两个栈中第一个相等的结点就是x,y的最近的公共祖先

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <malloc.h>
#include <stack>
#include <queue>
#include <bits/stdc++.h>

using namespace std;


typedef struct BiTNode{
    char data;
    struct BiTNode *left,*right;
}BiTNode,*BiTree;

typedef struct{
    BiTree t;
    int tag;
}Stack;


BiTree build()
{
    char c;
    BiTree st = nullptr;
    c=getchar();
    if(c!='#')

    {

        st = new BiTNode();
        st ->data = c;//已知为先序遍历,先填充根节点
        st ->left = build();//递归形式填充左分支
        st ->right = build();//递归形式填充左分支
    }
    return st;
}

void visit(BiTNode *x)
{

    cout<<x->data<<' ';
}

//后序非递归
void backVisitStack(BiTree root,char x ,char y)
{

    BiTNode* p = root;
    Stack s[100],s1[100];
    int top = 0;
    int top1 = 0;

    while( p != nullptr || top > 0){
        while(p != nullptr){
                s[++top].t = p;
                s[top].tag = 1;
                p = p->left;
        }
        while(top != 0 && s[top].tag == 2){
            if( s[top].t->data == x){
                for(int j = 1; j <= top; ++j)
                    s1[j] = s[j];
                    top1 = top;
            }
            if(s[top].t->data == y){
                for(int i = top; i > 0; --i){
                    for(int j = top1; j > 0; --j){
                        if(s[i].t->data == s1[j].t->data){
                            visit(s[i].t);
                            return ;
                        }
                    }
                }
            }

            --top;
        }

        if(top > 0){
            s[top].tag = 2;
            p = s[top].t->right;
        }
    }


    cout << endl;
}

/* 树的结构
        A
      /   \
     B     C
    / \   /
   D   E  F
  /     \
 G       H
*/



//先序序列 ABDG###E#H##CF###

// 根据先序 建树


int main()
{

    BiTree bt;
    bt = build();

    char x = 'G';
    char y = 'H';
    backVisitStack(bt,x,y);

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值