C++实现寻找最低公共父节点的方法

 更新时间:2014年09月18日 09:53:08   投稿:shichen2014  
这篇文章主要介绍了C++实现寻找最低公共父节点的方法,是数据结构中二叉树的一个经典算法,有一定的借鉴价值,需要的朋友可以参考下

本文实例讲述了C++实现寻找最低公共父节点的方法,是数据结构中二叉树的经典算法。分享给大家供大家参考。具体方法如下:

最低公共父节点,意思很好理解。

思路1:最低公共父节点满足这样的条件:两个节点分别位于其左子树和右子树,那么定义两个bool变量,leftFlag和rightFlag,如果在左子树中,leftFlag为true,如果在右子树中,rightFlag为true,仅当leftFlag == rightFlag == true时,才能满足条件。

实现代码如下:

#include <iostream>

using namespace std;

struct Node
{
 Node(int i = 0, Node *pLeft = NULL, Node *pRight = NULL) : data(i), left(pLeft),
 right(pRight) {}
 Node *left;
 Node *right;
 int data;
};

Node *constructNode(Node **pNode1, Node **pNode2)
{
 Node *node12 = new Node(12);
 Node *node11 = new Node(11);
 Node *node10 = new Node(10);
 Node *node9 = new Node(9, NULL, node12);
 Node *node8 = new Node(8, node11, NULL);
 Node *node7 = new Node(7);
 Node *node6 = new Node(6);
 Node *node5 = new Node(5, node8, node9);
 Node *node4 = new Node(4, node10);
 Node *node3 = new Node(3, node6, node7);
 Node *node2 = new Node(2, node4, node5);
 Node *node1 = new Node(1, node2, node3);

 *pNode1 = node6;
 *pNode2 = node12;

 return node1;
}

bool isNodeIn(Node *root, Node *node1, Node *node2)
{
 if (node1 == NULL || node2 == NULL)
 {
 throw("invalid node1 and node2");
 return false;
 }
 if (root == NULL)
 return false;

 if (root == node1 || root == node2)
 {
 return true;
 }
 else
 {
 return isNodeIn(root->left, node1, node2) || isNodeIn(root->right, node1, node2);
 }
}

Node *lowestFarther(Node *root, Node *node1, Node *node2)
{
 if (root == NULL || node1 == NULL || node2 == NULL || node1 == node2)
 {
 return NULL;
 }
 
 bool leftFlag = false;
 bool rightFlag = false;
 leftFlag = isNodeIn(root->left, node1, node2);
 rightFlag = isNodeIn(root->right, node1, node2);

 if (leftFlag == true && rightFlag == true)
 {
 return root;
 }
 else if (leftFlag == true)
 {
 return lowestFarther(root->left, node1, node2);
 }
 else
 {
 return lowestFarther(root->right, node1, node2);
 }
}

void main()
{
 Node *node1 = NULL;
 Node *node2 = NULL;
 Node *root = constructNode(&node1, &node2);

 cout << "node1: " << node1->data << endl;
 cout << "node2: " << node2->data << endl;
 cout << "root: " << root->data << endl;

 Node *father = lowestFarther(root, node1, node2);

 if (father == NULL)
 {
 cout << "no common father" << endl;
 }
 else
 {
 cout << "father: " << father->data << endl;
 }
}

这类问题在面试的时候常会遇到,对此需要考虑以下情形:

1. node1和node2指向同一节点,这个如何处理
2. node1或node2有不为叶子节点的可能性吗
3. node1或node2一定在树中吗

还要考虑一个效率问题,上述代码中用了两个递归函数,而且存在不必要的递归过程,仔细思考,其实一个递归过程足以解决此问题

实现代码如下:

#include <iostream>

using namespace std;

struct Node
{
 Node(int i = 0, Node *pLeft = NULL, Node *pRight = NULL) : data(i),
 left(pLeft), right(pRight) {}
 int data;
 Node *left;
 Node *right;
};

Node *constructNode(Node **pNode1, Node **pNode2) 
{ 
 Node *node12 = new Node(12); 
 Node *node11 = new Node(11); 
 Node *node10 = new Node(10); 
 Node *node9 = new Node(9, NULL, node12); 
 Node *node8 = new Node(8, node11, NULL); 
 Node *node7 = new Node(7); 
 Node *node6 = new Node(6); 
 Node *node5 = new Node(5, node8, node9); 
 Node *node4 = new Node(4, node10); 
 Node *node3 = new Node(3, node6, node7); 
 Node *node2 = new Node(2, node4, node5); 
 Node *node1 = new Node(1, node2, node3); 

 *pNode1 = node6; 
 *pNode2 = node5; 

 return node1; 
}

bool lowestFather(Node *root, Node *node1, Node *node2, Node *&dest)
{
 if (root == NULL || node1 == NULL || node2 == NULL || node1 == node2)
 return false;
 if (root == node1 || root == node2)
 return true;

 bool leftFlag = lowestFather(root->left, node1, node2, dest);
 bool rightFlag = lowestFather(root->right, node1, node2, dest);
 
 if (leftFlag == true && rightFlag == true)
 {
 dest = root;
 }
 if (leftFlag == true || rightFlag == true)
 return true;
}

int main()
{
 Node *node1 = NULL;
 Node *node2 = NULL;
 Node *root = constructNode(&node1, &node2);

 bool flag1 = false;
 bool flag2 = false;
 Node *dest = NULL;
 bool flag = lowestFather(root, node1, node2, dest);

 if (dest != NULL)
 {
 cout << "lowest common father: " << dest->data << endl;
 }
 else
 {
 cout << "no common father!" << endl;
 }

 return 0;
}

下面再换一种方式的写法如下:

#include <iostream>

using namespace std;

struct Node
{
 Node(int i = 0, Node *pLeft = NULL, Node *pRight = NULL) : data(i),
 left(pLeft), right(pRight) {}
 int data;
 Node *left;
 Node *right;
};

Node *constructNode(Node **pNode1, Node **pNode2) 
{ 
 Node *node12 = new Node(12); 
 Node *node11 = new Node(11); 
 Node *node10 = new Node(10); 
 Node *node9 = new Node(9, NULL, node12); 
 Node *node8 = new Node(8, node11, NULL); 
 Node *node7 = new Node(7); 
 Node *node6 = new Node(6); 
 Node *node5 = new Node(5, node8, node9); 
 Node *node4 = new Node(4, node10); 
 Node *node3 = new Node(3, node6, node7); 
 Node *node2 = new Node(2, node4, node5); 
 Node *node1 = new Node(1, node2, node3); 

 *pNode1 = node11; 
 *pNode2 = node12; 

 return node1; 
}

Node* lowestFather(Node *root, Node *node1, Node *node2)
{
 if (root == NULL || node1 == NULL || node2 == NULL || node1 == node2)
 return NULL;
 if (root == node1 || root == node2)
 return root;

 Node* leftFlag = lowestFather(root->left, node1, node2);
 Node* rightFlag = lowestFather(root->right, node1, node2);

 if (leftFlag == NULL)
 return rightFlag;
 else if (rightFlag == NULL)
 return leftFlag;
 else
 return root;
}

int main()
{
 Node *node1 = NULL;
 Node *node2 = NULL;
 Node *root = constructNode(&node1, &node2);

 bool flag1 = false;
 bool flag2 = false;
 Node *dest = NULL;
 Node* flag = lowestFather(root, node1, node2);

 if (flag != NULL)
 {
 cout << "lowest common father: " << flag->data << endl;
 }
 else
 {
 cout << "no common father!" << endl;
 }

 return 0;
}

希望本文所述对大家C++程序算法设计的学习有所帮助。

相关文章

  • C++ 位图及位图的实现原理

    C++ 位图及位图的实现原理

    位图实际上就是一个数组,因为数组有随机访问的功能,比较方便查找,这个数组一般是整形,今天通过本文给大家分享c++位图的实现原理及实现代码,感兴趣的朋友跟随小编一起看看吧
    2021-05-05
  • C语言实现数组移位、前移、后移与整体移动实例代码

    C语言实现数组移位、前移、后移与整体移动实例代码

    C语言中通常可以使用循环语句实现数组的移动,下面这篇文章主要给大家介绍了关于C语言实现数组移位、前移、后移与整体移动的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-03-03
  • 使用C语言实现vector动态数组的实例分享

    使用C语言实现vector动态数组的实例分享

    vector是指能够存放任意类型的动态数组,而C语言中并没有面向对象的C++那样内置vector类,所以我们接下来就来看一下使用C语言实现vector动态数组的实例,需要的朋友可以参考下
    2016-05-05
  • C++函数重载详解及实例代码

    C++函数重载详解及实例代码

    这篇文章主要介绍了C++函数重载详解及实例代码的相关资料,需要的朋友可以参考下
    2016-09-09
  • C++ map的简单使用实现

    C++ map的简单使用实现

    map是STL的一个关联容器,它以<key,value>一对一的形式存储,且map的内部自建一个红黑树,使得其可以自动排序,本文就介绍一下C++ map的简单使用,感兴趣的可以了解一下
    2021-05-05
  • C语言指针如何实现字符串逆序反转

    C语言指针如何实现字符串逆序反转

    这篇文章主要介绍了C语言指针如何实现字符串逆序反转,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • C++实现打地鼠游戏设计

    C++实现打地鼠游戏设计

    这篇文章主要为大家详细介绍了C++实现打地鼠游戏设计,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • C语言编写简单拼图游戏

    C语言编写简单拼图游戏

    这篇文章主要为大家详细介绍了C语言编写简单拼图游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • C语言野指针及如何规避详解

    C语言野指针及如何规避详解

    这篇文章主要为大家介绍了C语言野指针及如何规避详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • Visual Studio Code 从简介、安装到配置所需插件详细介绍

    Visual Studio Code 从简介、安装到配置所需插件详细介绍

    这篇文章给大家介绍到vs与vs code的区别,并且会详细介绍vscode的安装步骤,和我所了解过的插件配置,感兴趣的朋友跟随小编一起看看吧
    2020-03-03

最新评论