问题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;
}