最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

在這里插入圖片描述

在這里插入圖片描述

最近公共祖先定義

在這里插入圖片描述

在這里插入圖片描述

查找最近公共祖先

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

三叉鏈

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

代碼如下:

//三叉鏈
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é)點(diǎn)的祖先結(jié)點(diǎn)
		int lenp = 0, lenq = 0; //分別記錄p、q結(jié)點(diǎn)各自的祖先結(jié)點(diǎn)個(gè)數(shù)
		//統(tǒng)計(jì)p結(jié)點(diǎn)的祖先結(jié)點(diǎn)個(gè)數(shù)
		while (curp != root)
		{
			lenp++;
			curp = curp->parent;
		}
		//統(tǒng)計(jì)q結(jié)點(diǎn)的祖先結(jié)點(diǎn)個(gè)數(shù)
		while (curq != root)
		{
			lenq++;
			curq = curq->parent;
		}
		//longpath和shortpath分別標(biāo)記祖先路徑較長(zhǎng)和較短的結(jié)點(diǎn)
		TreeNode* longpath = p, *shortpath = q;
		if (lenp < lenq)
		{
			longpath = q;
			shortpath = p;
		}
		//p、q結(jié)點(diǎn)祖先結(jié)點(diǎn)個(gè)數(shù)的差值
		int count = abs(lenp - lenq);
		//先讓longpath往上走count個(gè)結(jié)點(diǎn)
		while (count--)
		{
			longpath = longpath->parent;
		}
		//再讓longpath和shortpath同時(shí)往上走,此時(shí)第一個(gè)相同的結(jié)點(diǎn)便是最近公共祖先結(jié)點(diǎn)
		while (longpath != shortpath)
		{
			longpath = longpath->parent;
			shortpath = shortpath->parent;
		}
		return longpath; //返回最近公共祖先結(jié)點(diǎn)
	}
};

二叉搜索樹

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

代碼如下:

//搜索二叉樹
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é)點(diǎn)中某一個(gè)結(jié)點(diǎn)的值等于根結(jié)點(diǎn)的值,則根結(jié)點(diǎn)就是這兩個(gè)結(jié)點(diǎn)的最近公共祖先
			return root;
		if (p->val < root->val&&q->val < root->val) //p、q結(jié)點(diǎn)的值都小于根結(jié)點(diǎn)的值,說(shuō)明這兩個(gè)結(jié)點(diǎn)的最近公共祖先在該樹的左子樹當(dāng)中
			return lowestCommonAncestor(root->left, p, q);
		else if (p->val > root->val&&q->val > root->val) //p、q結(jié)點(diǎn)的值都大于根結(jié)點(diǎn)的值,說(shuō)明這兩個(gè)結(jié)點(diǎn)的最近公共祖先在該樹的右子樹當(dāng)中
			return lowestCommonAncestor(root->right, p, q);
		else //p、q結(jié)點(diǎn)的值一個(gè)比根小一個(gè)比根大,說(shuō)明根就是這兩個(gè)結(jié)點(diǎn)的最近公共祖先
			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); //在左子樹找到了或是右子樹找到了,都說(shuō)明該結(jié)點(diǎn)在該樹當(dāng)中
	}
	TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
		if (p == root || q == root) //p、q結(jié)點(diǎn)中某一個(gè)結(jié)點(diǎn)為根結(jié)點(diǎn),則根結(jié)點(diǎn)就是這兩個(gè)結(jié)點(diǎn)的最近公共祖先
			return root;
		//判斷p、q結(jié)點(diǎn)是否在左右子樹
		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é)點(diǎn)都在左子樹,說(shuō)明這兩個(gè)結(jié)點(diǎn)的最近公共祖先也在左子樹當(dāng)中
			return lowestCommonAncestor(root->left, p, q);
		else if (IspInRight&&IsqInRight) //p、q結(jié)點(diǎn)都在右子樹,說(shuō)明這兩個(gè)結(jié)點(diǎn)的最近公共祖先也在右子樹當(dāng)中
			return lowestCommonAncestor(root->right, p, q);
		else //p、q結(jié)點(diǎn)一個(gè)在左子樹一個(gè)在右子樹,說(shuō)明根就是這兩個(gè)結(jié)點(diǎn)的最近公共祖先
			return root;
	}
};

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

看著似乎不太好理解,來(lái)看看下面的動(dòng)圖演示:

在這里插入圖片描述

代碼如下:

//普通二叉樹
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é)點(diǎn)可能是路徑當(dāng)中的結(jié)點(diǎn),先入棧

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

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

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

在這里插入圖片描述

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

相關(guān)文章

  • C++中關(guān)鍵字 override 的簡(jiǎn)析

    C++中關(guān)鍵字 override 的簡(jiǎn)析

    這篇小文來(lái)聊聊 C++中的關(guān)鍵字 override,它的含義其實(shí)兩句話就說(shuō)完了,但為了敘述的完整性,讓我們從虛函數(shù)說(shuō)起。感興趣的小伙伴可以跟著小編一起學(xué)習(xí)下面文章內(nèi)容
    2021-09-09
  • 利用QDir實(shí)現(xiàn)刪除選定文件目錄下的空文件夾

    利用QDir實(shí)現(xiàn)刪除選定文件目錄下的空文件夾

    這篇文章主要為大家詳細(xì)介紹了如何利用QDir實(shí)現(xiàn)刪除選定文件目錄下的空文件夾功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以動(dòng)手嘗試一下
    2022-08-08
  • C語(yǔ)言const關(guān)鍵字的用法詳解

    C語(yǔ)言const關(guān)鍵字的用法詳解

    今天探討const,首先來(lái)說(shuō)是將變量常量化。為什么要將變量常量化,原因有諸多好處有諸多。比如可以使數(shù)據(jù)更加安全不會(huì)被修改
    2022-08-08
  • Qt音視頻開發(fā)之視頻文件保存功能的實(shí)現(xiàn)

    Qt音視頻開發(fā)之視頻文件保存功能的實(shí)現(xiàn)

    和音頻存儲(chǔ)類似,視頻的存儲(chǔ)也對(duì)應(yīng)三種格式,視頻最原始的數(shù)據(jù)是yuv(音頻對(duì)應(yīng)pcm),視頻壓縮后的數(shù)據(jù)是h264(音頻對(duì)應(yīng)aac)。本文將利用Qt實(shí)現(xiàn)視頻文件保存功能,感興趣的可以了解一下
    2022-12-12
  • 關(guān)于C++中0是十進(jìn)制還是八進(jìn)制的問(wèn)題

    關(guān)于C++中0是十進(jìn)制還是八進(jìn)制的問(wèn)題

    本篇文章中,小編將為大家介紹關(guān)于C++中0是十進(jìn)制還是八進(jìn)制的問(wèn)題,有需要的朋友可以參考一下
    2013-04-04
  • C語(yǔ)言基礎(chǔ)全局變量與局部變量教程詳解

    C語(yǔ)言基礎(chǔ)全局變量與局部變量教程詳解

    此處對(duì)于全局與局部做一些簡(jiǎn)要的介紹,包括全局變量與局部變量,靜態(tài)全局變量與靜態(tài)局部變量,全局函數(shù)與靜態(tài)函數(shù),作者實(shí)屬初學(xué),文中若有理解不當(dāng)之處,還請(qǐng)朋友們不吝指正
    2021-11-11
  • C++11語(yǔ)法之右值引用的示例講解

    C++11語(yǔ)法之右值引用的示例講解

    右值引用,一般是在深拷貝的類,實(shí)現(xiàn)移動(dòng)構(gòu)造和移動(dòng)賦值,能夠解決左值引用無(wú)法做到的傳返回值的效率問(wèn)題,下面跟隨小編一起學(xué)習(xí)下C++11語(yǔ)法之右值引用的問(wèn)題
    2022-04-04
  • C++中的內(nèi)存對(duì)齊實(shí)例詳解

    C++中的內(nèi)存對(duì)齊實(shí)例詳解

    這篇文章主要介紹了C++中的內(nèi)存對(duì)齊實(shí)例詳解的相關(guān)資料,這里不僅提供實(shí)現(xiàn)方法及代碼還提供了手工制作圖,來(lái)幫助到大家理解這部分知識(shí),需要的朋友可以參考下
    2017-07-07
  • C++實(shí)現(xiàn)一個(gè)簡(jiǎn)易版的事件(Event)的示例代碼

    C++實(shí)現(xiàn)一個(gè)簡(jiǎn)易版的事件(Event)的示例代碼

    之前在?windows系統(tǒng)中開發(fā)應(yīng)用時(shí),?遇到需要進(jìn)行線程同步的時(shí)候幾乎都是使用的事件內(nèi)核對(duì)象?Event。本文為大家整理了C++實(shí)現(xiàn)一個(gè)簡(jiǎn)易版的事件(Event)的相關(guān)資料,需要的可以參考一下
    2022-11-11
  • 用C語(yǔ)言實(shí)現(xiàn)猜數(shù)字游戲

    用C語(yǔ)言實(shí)現(xiàn)猜數(shù)字游戲

    這篇文章主要為大家詳細(xì)介紹了用C語(yǔ)言實(shí)現(xiàn)猜數(shù)字游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-10-10

最新評(píng)論

天镇县| 康平县| 万安县| 子长县| 长春市| 柳河县| 巴青县| 衡阳市| 东宁县| 驻马店市| 潮安县| 台北县| 苍南县| 陆川县| 西贡区| 宜宾市| 井陉县| 河津市| 乌海市| 调兵山市| 福安市| 罗山县| 黄平县| 庆阳市| 鹿泉市| 色达县| 从江县| 东方市| 淅川县| 红安县| 亳州市| 鹿邑县| 昔阳县| 鹤峰县| 塔城市| 四川省| 九台市| 香格里拉县| 安康市| 合江县| 鸡东县|