Извините, я не смог устоять.
Помимо опечаток и ошибок, я считаю, что это может выглядеть еще проще:
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>
struct Node {
int data;
Node *parent = nullptr;
};
Node* findCommonAncestor(Node *pNode1, Node *pNode2)
{
// find paths of pNode1 and pNode2
std::vector<Node*> path1, path2;
for (; pNode1; pNode1 = pNode1->parent) path1.push_back(pNode1);
for (; pNode2; pNode2 = pNode2->parent) path2.push_back(pNode2);
// revert paths to make indexing simple
std::reverse(path1.begin(), path1.end());
std::reverse(path2.begin(), path2.end());
// compare paths
Node *pNode = nullptr; // ancestor
size_t n = std::min(path1.size(), path2.size());
for (size_t i = 0; i < n; ++i) {
if (path1[i] == path2[i]) pNode = path1[i];
else break;
}
// done
return pNode;
}
int main()
{
// sample tree:
/* 1
* |
* 2
* / \
* 3 4
* |
* 5
*/
Node node1 = { 1, nullptr };
Node node2 = { 2, &node1 };
Node node3 = { 3, &node2 };
Node node4 = { 4, &node2 };
Node node5 = { 5, &node4 };
Node *pNode = findCommonAncestor(&node3, &node5);
if (pNode) {
std::cout << "Lowest common ancestor: " << pNode->data << '\n';
} else {
std::cout << "No common ancestor found!\n";
}
}
Вывод:
Lowest common ancestor: 2
Демонстрация в реальном времени на coliru
Примечание:
Хотя использование iterator
s помогает сохранить общий код …
Я бы рассмотрел это как один из случаев, когда придерживаться простой старой индексации (иначе говоря, std::vector
) индексация упрощает вещи.