本文实例讲述了C++实现寻找最低公共父节点的方法,是数据结构中二叉树的经典算法。分享给大家供大家参考。具体方法如下:
最低公共父节点,意思很好理解。
思路1:最低公共父节点满足这样的条件:两个节点分别位于其左子树和右子树,那么定义两个bool变量,leftFlag和rightFlag,如果在左子树中,leftFlag为true,如果在右子树中,rightFlag为true,仅当leftFlag == rightFlag == true时,才能满足条件。
实现代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
#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一定在树中吗
还要考虑一个效率问题,上述代码中用了两个递归函数,而且存在不必要的递归过程,仔细思考,其实一个递归过程足以解决此问题
实现代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
#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;
}
|
下面再换一种方式的写法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
#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++程序算法设计的学习有所帮助。