在二叉树中找到俩个节点的最近公共祖先

#include "Tree.h"
using namespace std;

//后序遍历得到俩个节点的最近公共祖先,时间复杂度N
Node* lowestAnce(Node* head, Node* o1, Node* o2)
{
    if(head == nullptr || head == o1 || head == o2)
        return head;
    Node* left = lowestAnce(head->left, o1, o2);
    Node* right = lowestAnce(head->right, o1, o2);
    if(left != nullptr && right != nullptr)
        return head;

    return left != nullptr ? left : right;
}
//如果操作频繁请减少单次查询的时间(即可以先建立记录再查询)
//方法一:使用哈希表,建表的时间复杂度N,空间复杂度N,查询的时间复杂度h,h是二叉树的高度
class Record1
{
public:
    Record1(Node* head)
    {
        if(head != nullptr)
            nMap[head] = nullptr;
        setMap(head);
    }
    Node* query(Node* o1, Node* o2)
    {
        set<Node*> temp;
        while(nMap.find(o1) != nMap.end())
        {
            temp.insert(o1);
            o1 = nMap[o1];
        }
//        cout << "ssssssss" << endl;
//        set<Node*>::iterator iter;
//        for(iter = temp.begin(); iter != temp.end(); ++iter)
//            cout << (*iter)->value << endl;
        while(temp.find(o2) == temp.end())
        {
            o2 = nMap[o2];
           // cout << o2->value << endl;
        }
        //cout << "tttttt" << endl;
        return o2;
    }
private:
   map<Node*, Node*> nMap;
   void setMap(Node* head)
    {
        if(head == nullptr)
            return;
        if(head->left)
            nMap[head->left] = head;
        if(head->right)
            nMap[head->right]= head;
        setMap(head->left);
        setMap(head->right);
    }
};
//方法二:建立任意俩个节点的最近公共祖先记录
//空间复杂度N^2,建表的时间复杂度N^2,查询的时间复杂度1
class Record2
{
public:
    Record2(Node* head)
    {
        initMap(head);
        setMap(head);
    }
    Node* query(Node* o1, Node* o2)
    {
        if(o1 == o2)
            return o1;
        if(nMap.find(o1) != nMap.end())
            return nMap[o1][o2];
        if(nMap.find(o2) != nMap.end())
            return nMap[o2][o1];
        return nullptr;
    }

private:
    map<Node* , map<Node*, Node*> > nMap;
    void initMap(Node* head);
    void setMap(Node* head);
    void headRecord(Node* n, Node* h);
    void subRecord(Node* head);
    void preLeft(Node* L, Node* R, Node* h);
    void PreRight(Node* L, Node* R, Node* h);
};
void Record2::initMap(Node* head)
{
    if(head == nullptr)
        return;
    map<Node*, Node*> hMap;
    nMap[head] = hMap;
    initMap(head->left);
    initMap(head->right);
}
void Record2::setMap(Node* head)
{
    if(head == nullptr)
        return;
    headRecord(head->left, head);
    headRecord(head->right, head);
    subRecord(head);
    setMap(head->left);
    setMap(head->right);
}

void Record2::headRecord(Node* n, Node* h)
{
    if(n == nullptr)
        return;
    nMap[n][h] = h;
    headRecord(n->left, h);
    headRecord(n->right, h);
}
void Record2::subRecord(Node* head)
{
    if(head == nullptr)
        return;
    preLeft(head->left, head->right, head);
    subRecord(head->left);
    subRecord(head->right);
}
void Record2::preLeft(Node* L, Node* R, Node* h)
{
    if(L == nullptr)
        return;
    PreRight(L, R, h);
    preLeft(L->left, R, h);
    preLeft(L->right, R, h);
}
void Record2::PreRight(Node* L, Node* R, Node* h)
{
    if(R == nullptr)
        return;
    nMap[L][R] = h;
    PreRight(L, R->left, h);
    PreRight(L, R->right, h);
}

int main()
{
     Node* pNode0 = new Node(5);
    Node* pNode1 = new Node(3);
    Node* pNode2 = new Node(7);
    Node* pNode3 = new Node(2);
    Node* pNode4 = new Node(5);
    Node* pNode5 = new Node(6);
    Node* pNode6 = new Node(8);

    connectTree(pNode0, pNode1, pNode2);
    connectTree(pNode1, pNode3, pNode4);
    connectTree(pNode2, pNode5, pNode6);

    cout << lowestAnce(pNode0, pNode3, pNode6)->value << endl;
    Record1* re = new Record1(pNode0);
    cout << re->query(pNode3, pNode6)->value << endl;
    Record2* re2 = new Record2(pNode0);
    cout <<re2->query(pNode3, pNode6)->value << endl;
}

猜你喜欢

转载自blog.csdn.net/wzc2608/article/details/80875439
今日推荐