|
| 1 | +- 问题:给出一棵二叉平衡树的根节点,和两个子节点。要求找到两个节点最近的共同祖先。 |
| 2 | + - 思路: |
| 3 | + - 思考二叉平衡树的性质: |
| 4 | + 1. 每个节点最多有2个子节点,然而这对解题并没有什么用。 |
| 5 | + 2. 每个节点的值大于或者等于左节点的值,且每个节点的值小于或者等于右节点的值。这个性质是可以使用的。 |
| 6 | + - 考虑一个数轴,数轴上有3个点,根节点root,节点A,和节点B,节点A的值小于节点B的值,那么root在数轴上一共有3种情况: |
| 7 | + |
| 8 | +  |
| 9 | + |
| 10 | + - 思考共同祖先的性质: |
| 11 | + - 在二叉平衡树中,**两个节点的最近共同祖先的值必然夹在两个节点的值的中间**——如果root的值小于A,那么root必然位于A的左子树中;如果root的值大于B,那么root必然位于B的右子树中。所以,最近的共同祖先root的值必须夹在A和B的值之间。 |
| 12 | + - 由以上分析,可以写出一个算法的基本流程: |
| 13 | + - 如果A的值大于B的值,则交换A和B |
| 14 | + - 定义一个指针p, p指向root |
| 15 | + - 当p的值比A小时,此时向p的右子节点去寻找; |
| 16 | + - 当p的值比B大时,此时向p的左子节点去寻找; |
| 17 | + - 当p的值第一次夹在A和B中间时,返回p |
| 18 | + |
| 19 | + ```cpp |
| 20 | + #include <iostream> |
| 21 | + using namespace std; |
| 22 | + |
| 23 | + struct TreeNode{ |
| 24 | + TreeNode* lChild; |
| 25 | + TreeNode* rChild; |
| 26 | + int value; |
| 27 | + }; |
| 28 | + |
| 29 | + int GetTheNearestParent(TreeNode* root, TreeNode* a, TreeNode* b){ |
| 30 | + if(root == nullptr){ |
| 31 | + return -1; |
| 32 | + } |
| 33 | + |
| 34 | + TreeNode* p = root; |
| 35 | + if(a->value > b->value){ |
| 36 | + swap(a, b); |
| 37 | + } |
| 38 | + |
| 39 | + while(p != nullptr){ |
| 40 | + if(p->value > a->value && p->value > b->value){ |
| 41 | + p = p->lChild; |
| 42 | + } |
| 43 | + else if(p->value < a->value && p->value < b->value){ |
| 44 | + p = p->rChild; |
| 45 | + } |
| 46 | + else if(p->value > a->value && p->value < b->value){ |
| 47 | + return p->value; |
| 48 | + } |
| 49 | + else{ |
| 50 | + std::cout<< "error!" << std::endl; |
| 51 | + } |
| 52 | + } |
| 53 | + } |
| 54 | + |
| 55 | + int main() { |
| 56 | + // 创建一个二叉搜索树 |
| 57 | + TreeNode* root = new TreeNode(); |
| 58 | + root->value = 10; |
| 59 | + |
| 60 | + root->lChild = new TreeNode(); |
| 61 | + root->lChild->value = 5; |
| 62 | + |
| 63 | + root->rChild = new TreeNode(); |
| 64 | + root->rChild->value = 15; |
| 65 | + |
| 66 | + root->lChild->lChild = new TreeNode(); |
| 67 | + root->lChild->lChild->value = 3; |
| 68 | + |
| 69 | + root->lChild->rChild = new TreeNode(); |
| 70 | + root->lChild->rChild->value = 7; |
| 71 | + |
| 72 | + root->rChild->lChild = new TreeNode(); |
| 73 | + root->rChild->lChild->value = 12; |
| 74 | + |
| 75 | + root->rChild->rChild = new TreeNode(); |
| 76 | + root->rChild->rChild->value = 18; |
| 77 | + |
| 78 | + TreeNode* a = root->lChild->lChild; // 3 |
| 79 | + TreeNode* b = root->rChild->lChild; // 12 |
| 80 | + |
| 81 | + // 测试 GetTheNearestParent 函数 |
| 82 | + int nearestParentValue = GetTheNearestParent(root, a, b); |
| 83 | + cout << "The nearest common parent value is: " << nearestParentValue << endl; // 10 |
| 84 | + |
| 85 | + // 释放内存 |
| 86 | + delete root->lChild->lChild; |
| 87 | + delete root->lChild->rChild; |
| 88 | + delete root->rChild->lChild; |
| 89 | + delete root->rChild->rChild; |
| 90 | + delete root->lChild; |
| 91 | + delete root->rChild; |
| 92 | + delete root; |
| 93 | + |
| 94 | + return 0; |
| 95 | + } |
| 96 | + ``` |
0 commit comments