二叉樹中輸出節點的祖先以及找最近公共祖先
阿新 • • 發佈:2019-01-31
問題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;
}