/**
* 用二叉树链式存储实现 王道 P150 T13(求最近公共祖先)
*
* ①算法思想
* 非递归后序遍历中,遍历到m时,栈内的元素就是m自己和m的所有祖先的指针;
* 遍历到n时,栈内的元素就是n自己和n的所有祖先的指针。
* 把m和n的所有祖先从栈中自下而上分别拷贝到各自的数组栈中,然后找到两个数组中最靠后重复的元素,就是m和n的最近公共祖先。
* m和n的祖先数组个数可能不同也可能相同,但是会有一段元素是相同的,这就是两节点的公共祖先部分,
* 当m和n的数组栈长度不同时,
* 可以采用跑步思想(类似于链表中找公共节点),让个数较多的数组先出栈,直到两个数组长度相同,再一起跑,然后进行比较数组元素是否相等。
* 当m和n等长时,
* 就直接从后往前比较是否相等即可。
*
* 注:可以参考着王道书 P134 T5
*
*
* ②算法设计
*/
#include <stdio.h>
#include <iostream>
#define MaxSize 100
typedef struct BiTreeNode{
int data;
BiTreeNode *lchild,*rchild;
}BiTreeNode,*BiTree;
//P150 T13
BiTree Ancestor(BiTree T,BiTree m,BiTree n){//m、n是两个节点的指针
BiTree stack[MaxSize],p = T,mPre[MaxSize],nPre[MaxSize];//mPre和nPre两个数组用来保存m和n的祖先
int top = -1,tag[MaxSize] = {0};
int mtop = 0,ntop = 0;//mtop和ntop用来存一下mPre和nPre数组的长度,方便进行长度的比较
while(p || top != -1){
if(p){
stack[++top] = p;
tag[top] = 1;
p = p -> lchild;
}else{
if(tag[top] == 1){
tag[top] = 2;
p = stack[top];
p = p -> rchild;
}else{//说明是叶子节点了
p = stack[top--];
// Visit(p);
if(p == m){//此时栈内的元素就是m的所有祖先的指针
for (int i = 0; i <= top ; ++i) {
mPre[i] = stack[i];//把m的所有祖先都拷贝到mPre[]中
}
mtop = top;
}
if(p == n){//此时栈内的元素就是n的所有祖先的指针
for (int i = 0; i <= top ; ++i) {
nPre[i] = stack[i];//把n的所有祖先都拷贝到nPre[]中
}
ntop = top;
}
p = NULL;
}
}
}
while(mtop != ntop){
if(mtop > ntop)
mtop--;
else
ntop--;
}
//下面这个while可以直接这么写:
//while(mPre[top--] -> data != nPre[top--] -> data)
//注意这边使用while很方便,当while条件不满足时就说明找到了结果,然后直接return就可以了
while(mPre[top] -> data != nPre[top] -> data){
top--;
}
return mPre[top];//或者return nPre[top];
}
王道书 P150 T13(可以参考着P134 T5)
最新推荐文章于 2024-04-27 19:43:42 发布