欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

漫畫講解C語言中最近公共祖先的三種類型

 更新時間:2021年11月24日 09:06:22   作者:2021dragon  
這篇文章主要總結(jié)了使用C語言查找最近公共祖先的三種方法類型,用漫畫的方式講解原理定義,看上去更生動形象,幫助你更好的理解透徹,快來跟著本文往下看吧

在這里插入圖片描述

在這里插入圖片描述

最近公共祖先定義

在這里插入圖片描述

在這里插入圖片描述

查找最近公共祖先

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

三叉鏈

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

代碼如下:

//三叉鏈
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
	TreeNode *parent;
    TreeNode(int x) : val(x), left(NULL), right(NULL), parent(NULL) {}
};
class Solution {
public:
	TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
		TreeNode* curp = p, *curq = q; //用于遍歷p、q結(jié)點的祖先結(jié)點
		int lenp = 0, lenq = 0; //分別記錄p、q結(jié)點各自的祖先結(jié)點個數(shù)
		//統(tǒng)計p結(jié)點的祖先結(jié)點個數(shù)
		while (curp != root)
		{
			lenp++;
			curp = curp->parent;
		}
		//統(tǒng)計q結(jié)點的祖先結(jié)點個數(shù)
		while (curq != root)
		{
			lenq++;
			curq = curq->parent;
		}
		//longpath和shortpath分別標記祖先路徑較長和較短的結(jié)點
		TreeNode* longpath = p, *shortpath = q;
		if (lenp < lenq)
		{
			longpath = q;
			shortpath = p;
		}
		//p、q結(jié)點祖先結(jié)點個數(shù)的差值
		int count = abs(lenp - lenq);
		//先讓longpath往上走count個結(jié)點
		while (count--)
		{
			longpath = longpath->parent;
		}
		//再讓longpath和shortpath同時往上走,此時第一個相同的結(jié)點便是最近公共祖先結(jié)點
		while (longpath != shortpath)
		{
			longpath = longpath->parent;
			shortpath = shortpath->parent;
		}
		return longpath; //返回最近公共祖先結(jié)點
	}
};

二叉搜索樹

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

代碼如下:

//搜索二叉樹
struct TreeNode {
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
	TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
		if (p->val == root->val || q->val == root->val) //p、q結(jié)點中某一個結(jié)點的值等于根結(jié)點的值,則根結(jié)點就是這兩個結(jié)點的最近公共祖先
			return root;
		if (p->val < root->val&&q->val < root->val) //p、q結(jié)點的值都小于根結(jié)點的值,說明這兩個結(jié)點的最近公共祖先在該樹的左子樹當中
			return lowestCommonAncestor(root->left, p, q);
		else if (p->val > root->val&&q->val > root->val) //p、q結(jié)點的值都大于根結(jié)點的值,說明這兩個結(jié)點的最近公共祖先在該樹的右子樹當中
			return lowestCommonAncestor(root->right, p, q);
		else //p、q結(jié)點的值一個比根小一個比根大,說明根就是這兩個結(jié)點的最近公共祖先
			return root;
	}
};

普通二叉樹

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

代碼如下:

//普通二叉樹
struct TreeNode {
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
	bool Find(TreeNode* root, TreeNode* x)
	{
		if (root == nullptr) //空樹,查找失敗
			return false;
		if (root == x) //查找成功
			return true;

		return Find(root->left, x) || Find(root->right, x); //在左子樹找到了或是右子樹找到了,都說明該結(jié)點在該樹當中
	}
	TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
		if (p == root || q == root) //p、q結(jié)點中某一個結(jié)點為根結(jié)點,則根結(jié)點就是這兩個結(jié)點的最近公共祖先
			return root;
		//判斷p、q結(jié)點是否在左右子樹
		bool IspInLeft, IspInRight, IsqInLeft, IsqInRight;
		IspInLeft = Find(root->left, p);
		IspInRight = !IspInLeft;
		IsqInLeft = Find(root->left, q);
		IsqInRight = !IsqInLeft;

		if (IspInLeft&&IsqInLeft) //p、q結(jié)點都在左子樹,說明這兩個結(jié)點的最近公共祖先也在左子樹當中
			return lowestCommonAncestor(root->left, p, q);
		else if (IspInRight&&IsqInRight) //p、q結(jié)點都在右子樹,說明這兩個結(jié)點的最近公共祖先也在右子樹當中
			return lowestCommonAncestor(root->right, p, q);
		else //p、q結(jié)點一個在左子樹一個在右子樹,說明根就是這兩個結(jié)點的最近公共祖先
			return root;
	}
};

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

看著似乎不太好理解,來看看下面的動圖演示:

在這里插入圖片描述

代碼如下:

//普通二叉樹
struct TreeNode {
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
	bool FindPath(TreeNode* root, TreeNode* x, stack<TreeNode*>& path)
	{
		if (root == nullptr)
			return false;
		path.push(root); //該結(jié)點可能是路徑當中的結(jié)點,先入棧

		if (root == x) //該結(jié)點是最終結(jié)點,查找結(jié)束
			return true;

		if (FindPath(root->left, x, path)) //在該結(jié)點的左子樹找到了最終結(jié)點,查找結(jié)束
			return true;
		if (FindPath(root->right, x, path)) //在該結(jié)點的右子樹找到了最終結(jié)點,查找結(jié)束
			return true;

		path.pop(); //在該結(jié)點的左右子樹均沒有找到最終結(jié)點,該結(jié)點不可能是路徑當中的結(jié)點,該結(jié)點出棧
		return false; //在該結(jié)點處查找失敗
	}
	TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
		stack<TreeNode*> pPath, qPath;
		FindPath(root, p, pPath); //將從根到p結(jié)點的路徑存放到pPath當中
		FindPath(root, q, qPath); //將從根到q結(jié)點的路徑存放到qPath當中
		//longpath和shortpath分別標記長路徑和短路徑
		stack<TreeNode*>* longPath = &pPath, *shortPath = &qPath;
		if (pPath.size() < qPath.size())
		{
			longPath = &qPath;
			shortPath = &pPath;
		}
		//讓longPath先彈出差值個數(shù)據(jù)
		int count = longPath->size() - shortPath->size();
		while (count--)
		{
			longPath->pop();
		}
		//longPath和shortPath一起彈數(shù)據(jù),直到兩個棧頂?shù)慕Y(jié)點相同
		while (longPath->top() != shortPath->top())
		{
			longPath->pop();
			shortPath->pop();
		}
		return longPath->top(); //返回這個相同的結(jié)點,即最近公共祖先
	}
};

在這里插入圖片描述

到此這篇關(guān)于漫畫講解C語言中最近公共祖先的三種類型的文章就介紹到這了,更多相關(guān)C語言 公共祖先內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++泛型編程基本概念詳解

    C++泛型編程基本概念詳解

    這一篇介紹一下 C++ 編程中與面向?qū)ο蟛⒘械牧硪淮蠓种А盒途幊?,這一篇主要介紹函數(shù)模板、類模板和成員模板三大部分,需要的朋友可以參考下
    2021-08-08
  • C++構(gòu)造析構(gòu)賦值運算函數(shù)應(yīng)用詳解

    C++構(gòu)造析構(gòu)賦值運算函數(shù)應(yīng)用詳解

    構(gòu)造函數(shù)主要作用在于創(chuàng)建對象時為對象的成員屬性賦值,構(gòu)造函數(shù)由編譯器自動調(diào)用,無須手動調(diào)用;析構(gòu)函數(shù)主要作用在于對象銷毀前系統(tǒng)自動調(diào)用,執(zhí)行一 些清理工作
    2022-09-09
  • C語言中結(jié)構(gòu)體和共用體實例教程

    C語言中結(jié)構(gòu)體和共用體實例教程

    這篇文章主要給大家介紹了關(guān)于C語言中結(jié)構(gòu)體和共用體的相關(guān)資料,結(jié)構(gòu)體是一種自定義的復合數(shù)據(jù)類型,共用體也叫聯(lián)合體,使幾個不同類型的變量共占一段內(nèi)存(相互覆蓋),需要的朋友可以參考下
    2021-06-06
  • 詳解C++11中綁定器bind的原理與使用

    詳解C++11中綁定器bind的原理與使用

    C++11中引入的function機制,其中綁定器主要有三種:bind1st、bind2nd、bind(C++11)。本文就來和大家聊聊這些綁定器的底層實現(xiàn)原理與使用場景,需要的可以參考一下
    2022-12-12
  • 最小生成樹算法之Prim算法

    最小生成樹算法之Prim算法

    這篇文章主要講解了普里姆算法(Prim算法),圖論中的一種算法,可在加權(quán)連通圖里搜索最小生成樹,需要的朋友可以參考下
    2015-07-07
  • C語言的編程之美之內(nèi)存函數(shù)

    C語言的編程之美之內(nèi)存函數(shù)

    這篇文章主要介紹了C語言全部內(nèi)存操作函數(shù)的實現(xiàn)詳細講解,作者用圖文代碼實例講解的很清晰,有感興趣的同學可以研究下
    2021-09-09
  • C++的頭文件和實現(xiàn)文件詳解

    C++的頭文件和實現(xiàn)文件詳解

    這篇文章主要介紹了C++的頭文件和實現(xiàn)文件詳解的相關(guān)資料,需要的朋友可以參考下
    2015-01-01
  • Opencv實現(xiàn)對象提取與測量

    Opencv實現(xiàn)對象提取與測量

    這篇文章主要為大家詳細介紹了基于Opencv實現(xiàn)對象提取與測量,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • OpenCV實現(xiàn)輪廓的發(fā)現(xiàn)

    OpenCV實現(xiàn)輪廓的發(fā)現(xiàn)

    這篇文章主要為大家詳細介紹了OpenCV如何實現(xiàn)輪廓的發(fā)現(xiàn),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • 基于select、poll、epoll的區(qū)別詳解

    基于select、poll、epoll的區(qū)別詳解

    本篇文章是對select、poll、epoll之間的區(qū)別進行了詳細的分析介紹。需要的朋友參考下
    2013-05-05

最新評論