• 《剑指offer》第六十八题(树中两个结点的最低公共祖先)


    // 面试题68:树中两个结点的最低公共祖先
    // 题目:输入两个树结点,求它们的最低公共祖先。
    
    #include <iostream>
    #include "Tree.h"
    #include <list>
    
    using namespace std;
    
    bool GetNodePath(const TreeNode* pRoot, const TreeNode* pNode, list<const TreeNode*>& path)//找到根节点到指定节点的路径
    {
        if (pRoot == pNode)
            return true;
    
        path.push_back(pRoot);
    
        bool found = false;
    
        vector<TreeNode*>::const_iterator i = pRoot->m_vChildren.begin();//m_vChildren是个数组,详见Tree.h
        while (!found && i < pRoot->m_vChildren.end())
        {
            found = GetNodePath(*i, pNode, path);
            ++i;
        }
    
        if (!found)
            path.pop_back();
    
        return found;
    }
    
    const TreeNode* GetLastCommonNode//找最后一个公共节点
    (
        const list<const TreeNode*>& path1,
        const list<const TreeNode*>& path2
    )
    {
        list<const TreeNode*>::const_iterator iterator1 = path1.begin();
        list<const TreeNode*>::const_iterator iterator2 = path2.begin();//迭代器
    
        const TreeNode* pLast = nullptr;
    
        while (iterator1 != path1.end() && iterator2 != path2.end())
        {
            if (*iterator1 == *iterator2)
                pLast = *iterator1;
    
            iterator1++;
            iterator2++;
        }
    
        return pLast;
    }
    
    const TreeNode* GetLastCommonParent(const TreeNode* pRoot, const TreeNode* pNode1, const TreeNode* pNode2)
    {
        if (pRoot == nullptr || pNode1 == nullptr || pNode2 == nullptr)//判断边界
            return nullptr;
    
        list<const TreeNode*> path1;
        GetNodePath(pRoot, pNode1, path1);
    
        list<const TreeNode*> path2;
        GetNodePath(pRoot, pNode2, path2);
    
        return GetLastCommonNode(path1, path2);
    }
    
    // ====================测试代码====================
    void Test(const char* testName, const TreeNode* pRoot, const TreeNode* pNode1, const TreeNode* pNode2, TreeNode* pExpected)
    {
        if (testName != nullptr)
            printf("%s begins: ", testName);
    
        const TreeNode* pResult = GetLastCommonParent(pRoot, pNode1, pNode2);
    
        if ((pExpected == nullptr && pResult == nullptr) ||
            (pExpected != nullptr && pResult != nullptr && pResult->m_nValue == pExpected->m_nValue))
            printf("Passed.
    ");
        else
            printf("Failed.
    ");
    }
    
    // 形状普通的树
    //              1
    //            /   
    //           2     3
    //       /       
    //      4         5
    //     /       / |  
    //    6   7    8  9  10
    void Test1()
    {
        TreeNode* pNode1 = CreateTreeNode(1);
        TreeNode* pNode2 = CreateTreeNode(2);
        TreeNode* pNode3 = CreateTreeNode(3);
        TreeNode* pNode4 = CreateTreeNode(4);
        TreeNode* pNode5 = CreateTreeNode(5);
        TreeNode* pNode6 = CreateTreeNode(6);
        TreeNode* pNode7 = CreateTreeNode(7);
        TreeNode* pNode8 = CreateTreeNode(8);
        TreeNode* pNode9 = CreateTreeNode(9);
        TreeNode* pNode10 = CreateTreeNode(10);
    
        ConnectTreeNodes(pNode1, pNode2);
        ConnectTreeNodes(pNode1, pNode3);
    
        ConnectTreeNodes(pNode2, pNode4);
        ConnectTreeNodes(pNode2, pNode5);
    
        ConnectTreeNodes(pNode4, pNode6);
        ConnectTreeNodes(pNode4, pNode7);
    
        ConnectTreeNodes(pNode5, pNode8);
        ConnectTreeNodes(pNode5, pNode9);
        ConnectTreeNodes(pNode5, pNode10);
    
        Test("Test1", pNode1, pNode6, pNode8, pNode2);
    }
    
    // 树退化成一个链表
    //               1
    //              /
    //             2
    //            /
    //           3
    //          /
    //         4
    //        /
    //       5
    void Test2()
    {
        TreeNode* pNode1 = CreateTreeNode(1);
        TreeNode* pNode2 = CreateTreeNode(2);
        TreeNode* pNode3 = CreateTreeNode(3);
        TreeNode* pNode4 = CreateTreeNode(4);
        TreeNode* pNode5 = CreateTreeNode(5);
    
        ConnectTreeNodes(pNode1, pNode2);
        ConnectTreeNodes(pNode2, pNode3);
        ConnectTreeNodes(pNode3, pNode4);
        ConnectTreeNodes(pNode4, pNode5);
    
        Test("Test2", pNode1, pNode5, pNode4, pNode3);
    }
    
    // 树退化成一个链表,一个结点不在树中
    //               1
    //              /
    //             2
    //            /
    //           3
    //          /
    //         4
    //        /
    //       5
    void Test3()
    {
        TreeNode* pNode1 = CreateTreeNode(1);
        TreeNode* pNode2 = CreateTreeNode(2);
        TreeNode* pNode3 = CreateTreeNode(3);
        TreeNode* pNode4 = CreateTreeNode(4);
        TreeNode* pNode5 = CreateTreeNode(5);
    
        ConnectTreeNodes(pNode1, pNode2);
        ConnectTreeNodes(pNode2, pNode3);
        ConnectTreeNodes(pNode3, pNode4);
        ConnectTreeNodes(pNode4, pNode5);
    
        TreeNode* pNode6 = CreateTreeNode(6);
    
        Test("Test3", pNode1, pNode5, pNode6, nullptr);
    }
    
    // 输入nullptr
    void Test4()
    {
        Test("Test4", nullptr, nullptr, nullptr, nullptr);
    }
    
    int main(int argc, char* argv[])
    {
        Test1();
        Test2();
        Test3();
        Test4();
        system("pause");
        return 0;
    }
  • 相关阅读:
    转】使用Maven编译项目遇到——“maven编码gbk的不可映射字符”解决办法
    转】Maven学习总结(九)——使用Nexus搭建Maven私服
    转】Maven学习总结(八)——使用Maven构建多模块项目
    转】Maven学习总结(七)——eclipse中使用Maven创建Web项目
    转】Maven学习总结(六)——Maven与Eclipse整合
    Storm具体解释一、Storm 概述
    ThinkPHP 连接Oracle的配置写法,(使用Oci扩展而非PDO的写法)
    VBA怎样统计同一类型的数据的总和
    在html中禁用自己主动完毕
    Sort方法的扩展
  • 原文地址:https://www.cnblogs.com/CJT-blog/p/10551660.html
Copyright © 2020-2023  润新知