icoding数据结构——共同祖先(详细注释)

题目:

假设二叉树采用二叉链表方式存储, root指向根结点,p所指结点和q所指结点为二叉树中的两个结点,编写一个计算它们的最近的共同祖先,函数定义如下:

BiTNode * nearest_ancestor(BiTree root, BiTNode *p, BiTNode *q);

其中 root 指向二叉树的根结点,p 和 q 分别指向二叉树中的两个结点。
path函数及栈相关定义如下:

bool path(BiTNode* root, BiTNode* node, Stack* s);

#define Stack_Size 50
typedef BiTNode* ElemType;
typedef struct{
    ElemType elem[Stack_Size];
    int top;
}Stack;

void init_stack(Stack *S); // 初始化栈
bool push(Stack* S, ElemType x); //x 入栈
bool pop(Stack* S, ElemType *px); //出栈,元素保存到px所指的单元,函数返回true,栈为空时返回 false
bool top(Stack* S, ElemType *px); //获取栈顶元素,将其保存到px所指的单元,函数返回true,栈满时返回 false
bool is_empty(Stack* S);  // 栈为空时返回 true,否则返回 false

提示:在完成本题时,可利用 path 函数获取p和q两个结点到根结点之间的路径,之后再计算两条公共路径得出最近的共同祖先。

可以直接用path函数就很简单,题目已经给提示了。😊

代码:

#include <stdlib.h>
#include <stdio.h>
#include "bitree.h" //请不要删除,否则检查不通过


BiTNode * nearest_ancestor(BiTree root, BiTNode *p, BiTNode *q){
    // 分别用栈Sp和Sq记录从根节点到节点p和q的路径
    Stack Sp, Sq;
    init_stack(&Sp);
    init_stack(&Sq);
    path(root, p, &Sp);
    path(root, q, &Sq);

    // 由于公共祖先一定在同一层,所以先让两个栈的栈顶在同一层
    while (Sp.top != Sq.top) {
        if (Sq.top > Sp.top) {
            Sq.top--;
        }
        else {
            Sp.top--;
        }
    }

    // 依次弹出栈顶元素进行比较,找到最近公共祖先
    while (!is_empty(&Sq)) {
        BiTNode* pop_q = NULL;
        pop(&Sq, &pop_q);
        BiTNode* pop_p = NULL;
        pop(&Sp, &pop_p);
        if (pop_p == pop_q) {
            // 如果栈顶元素相等,则说明找到了最近公共祖先
            return pop_q;
        }
    }    
    // 如果没有找到最近公共祖先,则返回NULL
    return NULL;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值