二叉树共同祖先(c语言,非递归)

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

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

其中 root 指向二叉树的根结点,p 和 q 分别指向二叉树中的两个结点。
提示:在完成本题时,可利用 path 函数获取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

方法一:

BiTNode* nearest_ancestor(BiTree root, BiTNode* p, BiTNode* q)
{
    int num1 = 0, num2 = 0;
    Stack s1, s2;
    BiTNode *Node1[100], *Node2[100];
    init_stack(&s1); //初始化栈
    init_stack(&s2);
    
    path(root, p, &s1); //找到两个栈的路径
    path(root, q, &s2);
    
    while (!is_empty(&s1)) //弹出元素,由于是先序遍历,最开始可能是不同的元素。保存到Node中,同时总数加一
        pop(&s1, &Node1[num1++]);
    while (!is_empty(&s2))
        pop(&s2, &Node2[num2++]);
        
    for (int i = 0; i < num1; ++i) { //找两个路径相同之处
        for (int j = 0; j < num2; ++j) {
            if (Node1[i] == Node2[j]) {
                return Node1[i]; //找到则返回,后面都是相同的
            }
        }
    }
}

方法二:

BiTNode* nearest_ancestor(BiTree root, BiTNode* p, BiTNode* q)
{
    Stack s1, s2;
    BiTNode* Node1;
    init_stack(&s1);
    init_stack(&s2);
    path(root, p, &s1);
    path(root, q, &s2);
    Node1 = s1.elem[0];
    if (s1.elem[0] != s2.elem[0])
        return NULL;
    for (int i = 1; i < s1.top && i < s2.top; i++) {
        if (s1.elem[i] != s2.elem[i])
            return Node1;
        Node1 = s1.elem[i];
    }
    return Node1;
}

你可能感兴趣的:(算法相关题目)