/*
二叉链表非递归 查找两个结点的最近公共结点
思路:
把一个结点的全部父结点都放到栈中(类似于查找从根结点到某一结点的路径)
依次出栈判断这棵树的后代中是否包括另一个结点
*/
#include <iostream>
#include <cstdlib>
using namespace std;
const int maxsize = 100;
typedef struct BiTNode{
char data;
struct BiTNode *lchild, *rchild;
}*BiTree;
void createTree(BiTree &T){
char c;
cin >> c;
if(c == '#')
T = NULL;
else{
T = (BiTree)malloc(sizeof(BiTNode));
T->data = c;
createTree(T->lchild);
createTree(T->rchild);
}
}
//将结点c的全部祖先结点依次入栈
BiTree stack[maxsize];
int top = -1;
void getNode(BiTree T, char c){
BiTree p;
int tag[maxsize]; //0表示该结点未被扫描过
p = T;
do{
//靠左的结点全部入栈
while(p){
stack[++top] = p; //结点入栈
tag[top] = 0;
p = p->lchild;
}
//栈非空
if(top>=0){
//结点已经访问过
if(tag[top] == 1){
if(stack[top]->data == c){
break; //结点不重复就退出,结点有重复就继续
}
top--;
}
//结点未访问过
else{
p = stack[top];
p = p->rchild; //扫描右结点
tag[top] = 1; //该结点已被扫描过
}
}
}while(top>=0 || p); //栈非空 或者 p结点不为空--继续循环
}
//判断树T的后代结点中是否有结点c(不能用遍历算法的递归形式,那样没办法判断没有所要查找结点的情况)
bool preSearch(BiTree T, char c){
BiTree p, s[maxsize];
int top;
if(T){
top = 1;
s[top] = T;
while(top>0){ //栈不空
p = s[top--]; //退栈并访问该结点
//这里要注意判断孩子结点是否是要找的结点的前提必须保证p的左右结点非空
if(p->rchild) {
s[++top] = p->rchild; //右孩子进栈
if(s[top]->data == c)
return true;
}
if(p->rchild) {
s[++top] = p->lchild; //左孩子进栈
if(s[top]->data == c)
return true;
}
}
}
return false;
}
//找结点v和结点c的最近公共祖先结点
BiTree findFirstCommonParentNode(BiTree T, char c, char v){
//把结点c的全部父结点入栈
getNode(T, c);
//栈不空
while(top>-1){
BiTree t = stack[top--];
//判断树t的后代结点中是否包括结点v
if(preSearch(t, v))
return t;
}
return NULL;
}
int main(){
BiTree T, p;
char c, v;
T = (BiTree)malloc(sizeof(BiTNode));
cout << "输入树的结点:";
createTree(T);
cout << "输入带判断的结点:";
cin >> c >> v;
p = findFirstCommonParentNode(T, c, v) ;
cout << "公共结点:" << p->data << endl;
return 0;
}
树(二叉链表,非递归)两结点的最近公共祖先结点
最新推荐文章于 2023-06-23 20:09:27 发布