C++實(shí)現(xiàn)尋找最低公共父節(jié)點(diǎn)的方法
本文實(shí)例講述了C++實(shí)現(xiàn)尋找最低公共父節(jié)點(diǎn)的方法,是數(shù)據(jù)結(jié)構(gòu)中二叉樹的經(jīng)典算法。分享給大家供大家參考。具體方法如下:
最低公共父節(jié)點(diǎn),意思很好理解。
思路1:最低公共父節(jié)點(diǎn)滿足這樣的條件:兩個(gè)節(jié)點(diǎn)分別位于其左子樹和右子樹,那么定義兩個(gè)bool變量,leftFlag和rightFlag,如果在左子樹中,leftFlag為true,如果在右子樹中,rightFlag為true,僅當(dāng)leftFlag == rightFlag == true時(shí),才能滿足條件。
實(shí)現(xiàn)代碼如下:
#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;
}
}
這類問題在面試的時(shí)候常會(huì)遇到,對(duì)此需要考慮以下情形:
1. node1和node2指向同一節(jié)點(diǎn),這個(gè)如何處理
2. node1或node2有不為葉子節(jié)點(diǎn)的可能性嗎
3. node1或node2一定在樹中嗎
還要考慮一個(gè)效率問題,上述代碼中用了兩個(gè)遞歸函數(shù),而且存在不必要的遞歸過程,仔細(xì)思考,其實(shí)一個(gè)遞歸過程足以解決此問題
實(shí)現(xiàn)代碼如下:
#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;
}
希望本文所述對(duì)大家C++程序算法設(shè)計(jì)的學(xué)習(xí)有所幫助。
相關(guān)文章
C++瓦片地圖坐標(biāo)轉(zhuǎn)換的實(shí)現(xiàn)詳解
常見的瓦片地圖有矩形、菱形、正六邊形幾種。此文章主要討論菱形瓦片,也就是大家常說的2.5D,斜45度瓦片地圖。比如《紅警2》、《帝國時(shí)代2》都是采用這種技術(shù)2022-09-09
C++?Boost?StringAlgorithms超詳細(xì)講解
Boost是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱。Boost庫是一個(gè)可移植、提供源代碼的C++庫,作為標(biāo)準(zhǔn)庫的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱2022-11-11
C++中std::thread{}和std::thread()用法
std::thread{}和std::thread()在C++中都可以用于創(chuàng)建線程對(duì)象,但std::thread{}作為C++11引入的統(tǒng)一初始化,更推薦使用,因?yàn)樗踩?、更易讀,且避免了隱式類型轉(zhuǎn)換2024-11-11
cmake添加一個(gè)庫的實(shí)現(xiàn)步驟
本文主要介紹了cmake添加一個(gè)庫的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06

