#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
今日推荐
周排行