二叉链表之寻找两节点的最近公共祖先☆

题目:p、q分别为指向该二叉树中任意两个节点的指针,试编写算法ancestor(root,p,q,r),找到p、q的最近公共祖先节点r
分析:
        上一道题其实可以给我们一些启示,就是我们可以将任意节点的祖先存起来,那这里我们也可以用两个栈,分别将p、q
        的祖先存在栈中,因为栈顶是最近的祖先节点,所以我们可以一次往下寻找相同节点,第一次找到的相同节点便是最近公共
        祖先节点。

代码如下:

struct biTree {
	char data;
	struct biTree *lchild;
	struct biTree *rchild;
};
struct Stack {
	biTree *arr;
	int len;
	int top;
};
#include <stdio.h>
#include <stdlib.h>
void findAncestor(Stack *s, biTree *m, biTree *x) {//这里将寻找祖先节点的方法封装起来
	struct biTree *r = (struct biTree *)malloc(sizeof(struct biTree));
	bool empty(Stack *);
	bool pushS(Stack *, biTree*);
	bool pop(Stack *);
	biTree *top(Stack *);//返回得是一个指针
	while (m || !empty(s)) {
		if (m) {//一路将所有左孩子入栈
			pushS(s, m);
			m = m->lchild;
		}
		else {//没有左孩子,
			m = top(s);
			if (m->rchild && m != r) {//将右子树的所有左孩子入栈
				r = m;
				m = m->rchild;
			}
			else {//当既没有左孩子也没有右孩子时,该出栈了
				pop(s);//被查找元素先出栈
				if (m->data == x->data) {//找到了,那么如果栈中有元素,那全都是它的祖先
					break;
				}
				m = NULL;//一定要将p置空,不然又会把m的左孩子入栈
			}
		}
	}
}
void findNearestAncestor(biTree *T, biTree *p, biTree *q, biTree **r) {
	int count = 0;
	struct biTree *m = T;//另起指针m,指向根节点
	void nodeNum(biTree *, int *);
	nodeNum(T, &count);//统计节点个数
	struct Stack *sp, *sq;
	Stack *createStack(int);
	sp = createStack(count);
	sq = createStack(count);

	findAncestor(sp, m, p);//寻找p节点的祖先
	findAncestor(sq, m, q);//寻找q节点的祖先

	//经过上面的操作,栈sp和sq里面已经存好了p、q各自的祖先,接下来便是寻找最近祖先
	bool contain(Stack *,biTree *);
	bool empty(Stack *);
	bool pushS(Stack *, biTree*);
	bool pop(Stack *);
	biTree *top(Stack *);//返回得是一个指针
	while (!empty(sp)) {//当sp不空
		*r = top(sp);
		if (contain(sq,*r)) {//判断sq中知否包含d
			break;
		}
		pop(sp);
	}
}
int main() {
	int count = 0;
	struct biTree *T = (struct biTree *)malloc(sizeof(struct biTree)), *p, *q;
	struct biTree *r = (struct biTree *)malloc(sizeof(struct biTree));
	biTree *create(biTree *);

	T = create(T);
	p = T->lchild->lchild->rchild;//手动指定一个节点,切记不要指成NULL了
	q = T->rchild->rchild;
	//p = T->lchild;
	//q = T->rchild;
	findNearestAncestor(T, p, q, &r);//记得这里要将r的地址传过去,才能进行改变
	printf("p q最近公共结点为值为:%c",r->data);
	return 0;
}

  你需要跟自己比的唯一一个人,就是以前的自己。你需要比一个人变得更好,那个人就是此刻的你。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北街学长

你的鼓励使我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值