二叉树求两节点最低公共祖先,求随意两节点距离
-------1.求最低公共祖先LCA( Lowest Common Ancestor )
什么是最低公共祖先?例如以下图。2与3的LCA是1;1与4的LCA是1;4与5的LCA是2。
那么给定两个节点n1和n2,如今要找出它们的LCA,怎样找?首先分析一下,n1和n2有几种情况?第一种。n1和n2分别在一个节点的左右子树中,比方4和5,LCA就是2,5和6,LCA就是1。2和3,LCA就是1;另外一种。n1和n2都在左子树或右子树,比方2和4,LCA就是2,1和4。LCA就是1。
一共这两种情况,事实上一点也不难。看代码实现吧。
/* 仅仅用一次遍历解决LCA */ #include <iostream> using namespace std; struct Node { Node *left, *right; int key; }; Node* newNode(int key) { Node *temp = new Node; temp->key = key; temp->left = temp->right = nullptr; return temp; } // 返回n1和n2的LCA的指针 Node * findLCA(Node* root, int n1, int n2) { if (root == nullptr) return nullptr; if (root->key == n1 || root->key == n2) return root; Node * left = findLCA(root->left, n1, n2); Node * right = findLCA(root->right, n1, n2); if (left&&right)//假设n1和n2分别在左右子树中 return root; return (left != nullptr ?left : right); } //測试 int main() { // 构造上面图中的树 Node * root = newNode(1); root->left = newNode(2); root->right = newNode(3); root->left->left = newNode(4); root->left->right = newNode(5); root->right->left = newNode(6); root->right->right = newNode(7); cout << "LCA(4, 5) = " << findLCA(root, 4, 5)->key; cout << "\nLCA(4, 6) = " << findLCA(root, 4, 6)->key; cout << "\nLCA(3, 4) = " << findLCA(root, 3, 4)->key; cout << "\nLCA(2, 4) = " << findLCA(root, 2, 4)->key; cout << endl; return 0; }
------2.求随意两节点距离:
对于普通的二叉树,怎样找到两个给定节点之家的距离?距离是指连接两个节点须要的最小的边的条数。
比如以下的二叉树:
代码例如以下:
#include <iostream> using namespace std; struct Node { Node *left, *right; int key; }; Node* newNode(int key) { Node *temp = new Node; temp->key = key; temp->left = temp->right = nullptr; return temp; } int FindLevel(Node * _root, int node)//返回node节点在root中的第几层。-1代表在子树下未找到node { if (_root == nullptr) return -1; if (_root->key == node) return 0; int level = FindLevel(_root->left, node);//先在左子树找 if (level == -1)//假设左子树没找到,在右子树找 level = FindLevel(_root->right, node); if (level != -1)//在找到node的时候,递归一个一个结束,逐渐加一 return level + 1; return -1; } Node * findLCA(Node* root, int n1, int n2)//找到n1和n2的LCA(已在上部分讲过怎样求解LCA的问题) { if (root == nullptr) return nullptr; if (root->key == n1 || root->key == n2) return root; Node * left = findLCA(root->left, n1, n2); Node * right = findLCA(root->right, n1, n2); if (left&&right)//假设n1和n2分别在左右子树中 return root; return (left != nullptr ?left : right); } int DistanceNodes(Node * _root, int n1, int n2) { Node * lca = findLCA(_root, n1, n2); int lca_level = FindLevel(_root, lca->key); int n1_level = FindLevel(_root, n1); int n2_level = FindLevel(_root, n2); return (n1_level - lca_level) + (n2_level - lca_level);//也就是n1_level+n2_level-2*lca_level,只是前者这样写更easy理解 } int main() { Node * root = newNode(1); root->left = newNode(2); root->right = newNode(3); root->left->left = newNode(4); root->left->right = newNode(5); root->right->left = newNode(6); root->right->right = newNode(7); root->right->left->right = newNode(8); cout << "Dist(8,7) = " << DistanceNodes(root, 8, 7) << endl; cout << "Dist(8,3) = " << DistanceNodes(root, 8, 3) << endl; cout << "Dist(8,2) = " << DistanceNodes(root, 8, 2) << endl; return 0; }
执行例如以下:
二叉树----第一篇(构造,遍历。求节点,求叶子)參考链接:http://blog.csdn.net/laojiu_/article/details/50196823
參考自:http://www.acmerblog.com/distance-between-given-keys-5995.html