Icoding题解
题干
共同祖先
假设二叉树采用二叉链表方式存储, root指向根结点,p所指结点和q所指结点为二叉树中的两个结点,编写一个计算它们的最近的共同祖先,函数定义如下:
BiTNode * nearest_ancestor(BiTree root, BiTNode *p, BiTNode *q);
其中 root 指向二叉树的根结点,p 和 q 分别指向二叉树中的两个结点。
提示:在完成本题时,可利用 path 函数获取p和q两个结点到根结点之间的路径,之后再计算两条公共路径得出最近的共同祖先。path函数及栈相关定义如下:
遍历所使用栈的相关操作如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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); bool pop(Stack* S, ElemType *px); bool top(Stack* S, ElemType *px); bool is_empty(Stack* S);
|
分析
- 简要分析题干:
得到距离p和q两个结点最近的结点,换言之,求某 node 到 p、q 路径之和的最小值。可以用path求得两个结点之间是否有路径。
- 应当注意的问题:
- 把
树二叉树
版块的路径
题给做了,可以更方便地理解这道题
- 当然,先写这道题也没什么问题,只需要理解清楚path这个函数提供的功能即可:path的底部是根结点,顶部是目标结点
- 树的基本概念与操作
- 树的遍历
- 解题思路:
- 声明两个栈,用于存放根分别到P、Q的路径
- 将两个栈的大小保持一致(看代码更容易理解为什么这么做)
- 同时出栈元素并比较出栈元素,第一对相等的就是距离P、Q最近的祖先
核心的思想就在于,根到某个结点的路径是唯一的,也就是说,根到共同祖先的路径是唯一的。我们通过两个栈存放了根到P、Q的路径,路径的长短可能不一致,但是我们可以通过某些手段,使得两个栈的top齐平,且共同祖先不可能存在于被我们舍弃掉的那部分路径中,否则根到共同祖先的路径是不唯一的!
注释代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| BiTNode * nearest_ancestor(BiTree root, BiTNode *p, BiTNode *q) { if (!root || !p || !q) { return NULL; }
Stack Path_P; Stack Path_Q; init_stack(&Path_P); init_stack(&Path_Q);
if (!path(root, p, &Path_P)) return NULL; if (!path(root, q, &Path_Q)) return NULL;
while(Path_P.top != Path_Q.top) { if (Path_P.top > Path_Q.top) Path_P.top--; else Path_Q.top--; }
ElemType Temp_Ptr_P; ElemType Temp_Ptr_Q; while (!is_empty(&Path_P)) { pop(&Path_P, &Temp_Ptr_P); pop(&Path_P, &Temp_Ptr_P); if (Temp_Ptr_P == Temp_Ptr_Q) { return Temp_Ptr_P; } }
return false; }
|
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| BiTNode * nearest_ancestor(BiTree root, BiTNode *p, BiTNode *q){ Stack PathP; Stack PathQ; init_stack(&PathP); init_stack(&PathQ); if(!path(root, p, &PathP)) return NULL; if(!path(root, q, &PathQ)) return NULL; ElemType Temp_P; ElemType Temp_Q; while(PathP.top != PathQ.top) { if(PathP.top > PathQ.top) PathP.top--; else PathQ.top--; } while(!is_empty(&PathP)) { pop(&PathP, &Temp_P); pop(&PathQ, &Temp_Q); if(Temp_P == Temp_Q) return Temp_P; } return NULL; }
|