日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > > 充電吧
[導(dǎo)讀]昨天花了一個晚上為《編程之美》,在豆瓣寫了一篇書評《遲來的書評和感想──給喜愛編程的朋友》。書評就不轉(zhuǎn)載到這里了,取而代之,在這里介紹書里其中一條問題的另一個解法。這個解法比較簡短易讀及降低了空間復(fù)雜

昨天花了一個晚上為《編程之美》,在豆瓣寫了一篇書評《遲來的書評和感想──給喜愛編程的朋友》。書評就不轉(zhuǎn)載到這里了,取而代之,在這里介紹書里其中一條問題的另一個解法。這個解法比較簡短易讀及降低了空間復(fù)雜度,或者可以說覺得比較「美」吧。

問題定義

如果我們把二叉樹看成一個圖,父子節(jié)點(diǎn)之間的連線看成是雙向的,我們姑且定義"距離"為兩節(jié)點(diǎn)之間邊的個數(shù)。寫一個程序求一棵二叉樹中相距最遠(yuǎn)的兩個節(jié)點(diǎn)之間的距離。

書上的解法

書中對這個問題的分析是很清楚的,我嘗試用自己的方式簡短覆述。

計算一個二叉樹的最大距離有兩個情況:

情況A: 路徑經(jīng)過左子樹的最深節(jié)點(diǎn),通過根節(jié)點(diǎn),再到右子樹的最深節(jié)點(diǎn)。情況B: 路徑不穿過根節(jié)點(diǎn),而是左子樹或右子樹的最大距離路徑,取其大者。

只需要計算這兩個情況的路徑距離,并取其大者,就是該二叉樹的最大距離。

我也想不到更好的分析方法。

但接著,原文的實(shí)現(xiàn)就不如上面的清楚 (源碼可從這里下載):

//?數(shù)據(jù)結(jié)構(gòu)定義
struct?NODE
{
	NODE*?pLeft;???????	//?左子樹
	NODE*?pRight;??????	//?右子樹
	int?nMaxLeft;??????	//?左子樹中的最長距離
	int?nMaxRight;?????	//?右子樹中的最長距離
	char?chValue;????	//?該節(jié)點(diǎn)的值
};

int?nMaxLen?=?0;

//?尋找樹中最長的兩段距離
void?FindMaxLen(NODE*?pRoot)
{
	//?遍歷到葉子節(jié)點(diǎn),返回
	if(pRoot?==?NULL)
	{
		return;
	}

	//?如果左子樹為空,那么該節(jié)點(diǎn)的左邊最長距離為0
	if(pRoot?->?pLeft?==?NULL)
	{
		pRoot?->?nMaxLeft?=?0;?
	}

	//?如果右子樹為空,那么該節(jié)點(diǎn)的右邊最長距離為0
	if(pRoot?->?pRight?==?NULL)
	{
		pRoot?->?nMaxRight?=?0;
	}

	//?如果左子樹不為空,遞歸尋找左子樹最長距離
	if(pRoot?->?pLeft?!=?NULL)
	{
		FindMaxLen(pRoot?->?pLeft);
	}

	//?如果右子樹不為空,遞歸尋找右子樹最長距離
	if(pRoot?->?pRight?!=?NULL)
	{
		FindMaxLen(pRoot?->?pRight);
	}

	//?計算左子樹最長節(jié)點(diǎn)距離
	if(pRoot?->?pLeft?!=?NULL)
	{
		int?nTempMax?=?0;
		if(pRoot?->?pLeft?->?nMaxLeft?>?pRoot?->?pLeft?->?nMaxRight)
		{
			nTempMax?=?pRoot?->?pLeft?->?nMaxLeft;
		}
		else
		{
			nTempMax?=?pRoot?->?pLeft?->?nMaxRight;
		}
		pRoot?->?nMaxLeft?=?nTempMax?+?1;
	}

	//?計算右子樹最長節(jié)點(diǎn)距離
	if(pRoot?->?pRight?!=?NULL)
	{
		int?nTempMax?=?0;
		if(pRoot?->?pRight?->?nMaxLeft?>?pRoot?->?pRight?->?nMaxRight)
		{
			nTempMax?=?pRoot?->?pRight?->?nMaxLeft;
		}
		else
		{
			nTempMax?=?pRoot?->?pRight?->?nMaxRight;
		}
		pRoot?->?nMaxRight?=?nTempMax?+?1;
	}

	//?更新最長距離
	if(pRoot?->?nMaxLeft?+?pRoot?->?nMaxRight?>?nMaxLen)
	{
		nMaxLen?=?pRoot?->?nMaxLeft?+?pRoot?->?nMaxRight;
	}
}

這段代碼有幾個缺點(diǎn):

算法加入了侵入式(intrusive)的資料nMaxLeft, nMaxRight使用了全局變量 nMaxLen。每次使用要額外初始化。而且就算是不同的獨(dú)立資料,也不能在多個線程使用這個函數(shù)邏輯比較復(fù)雜,也有許多 NULL 相關(guān)的條件測試。我的嘗試

我認(rèn)為這個問題的核心是,情況A?及 B 需要不同的信息: A 需要子樹的最大深度,B 需要子樹的最大距離。只要函數(shù)能在一個節(jié)點(diǎn)同時計算及傳回這兩個信息,代碼就可以很簡單:

#includeusing?namespace?std;

struct?NODE
{
	NODE?*pLeft;
	NODE?*pRight;
};

struct?RESULT
{
	int?nMaxDistance;
	int?nMaxDepth;
};

RESULT?GetMaximumDistance(NODE*?root)
{
	if?(!root)
	{
		RESULT?empty?=?{?0,?-1?};	//?trick:?nMaxDepth?is?-1?and?then?caller?will?plus?1?to?balance?it?as?zero.
		return?empty;
	}

	RESULT?lhs?=?GetMaximumDistance(root->pLeft);
	RESULT?rhs?=?GetMaximumDistance(root->pRight);

	RESULT?result;
	result.nMaxDepth?=?max(lhs.nMaxDepth?+?1,?rhs.nMaxDepth?+?1);
	result.nMaxDistance?=?max(max(lhs.nMaxDistance,?rhs.nMaxDistance),?lhs.nMaxDepth?+?rhs.nMaxDepth?+?2);
	return?result;
}

計算 result 的代碼很清楚;nMaxDepth 就是左子樹和右子樹的深度加1;nMaxDistance 則取 A 和 B 情況的最大值。

為了減少 NULL 的條件測試,進(jìn)入函數(shù)時,如果節(jié)點(diǎn)為 NULL,會傳回一個 empty 變量。比較奇怪的是 empty.nMaxDepth = -1,目的是讓調(diào)用方 +1 后,把當(dāng)前的不存在的 (NULL) 子樹當(dāng)成最大深度為 0。

除了提高了可讀性,這個解法的另一個優(yōu)點(diǎn)是減少了 O(節(jié)點(diǎn)數(shù)目) 大小的侵入式資料,而改為使用 O(樹的最大深度) 大小的棧空間。這個設(shè)計使函數(shù)完全沒有副作用(side effect)。

測試代碼

以下也提供測試代碼給讀者參考 (頁數(shù)是根據(jù)第7次印刷,節(jié)點(diǎn)是由上至下、左至右編號):

void?Link(NODE*?nodes,?int?parent,?int?left,?int?right)
{
	if?(left?!=?-1)
		nodes[parent].pLeft?=?&nodes[left];?

	if?(right?!=?-1)
		nodes[parent].pRight?=?&nodes[right];
}

void?main()
{
	//?P.?241?Graph?3-12
	NODE?test1[9]?=?{?0?};
	Link(test1,?0,?1,?2);
	Link(test1,?1,?3,?4);
	Link(test1,?2,?5,?6);
	Link(test1,?3,?7,?-1);
	Link(test1,?5,?-1,?8);
	cout?<<?"test1:?"?<<?GetMaximumDistance(&test1[0]).nMaxDistance?<<?endl;

	//?P.?242?Graph?3-13?left
	NODE?test2[4]?=?{?0?};
	Link(test2,?0,?1,?2);
	Link(test2,?1,?3,?-1);
	cout?<<?"test2:?"?<<?GetMaximumDistance(&test2[0]).nMaxDistance?<<?endl;

	//?P.?242?Graph?3-13?right
	NODE?test3[9]?=?{?0?};
	Link(test3,?0,?-1,?1);
	Link(test3,?1,?2,?3);
	Link(test3,?2,?4,?-1);
	Link(test3,?3,?5,?6);
	Link(test3,?4,?7,?-1);
	Link(test3,?5,?-1,?8);
	cout?<<?"test3:?"?<<?GetMaximumDistance(&test3[0]).nMaxDistance?<<?endl;

	//?P.?242?Graph?3-14
	//?Same?as?Graph?3-2,?not?test

	//?P.?243?Graph?3-15
	NODE?test4[9]?=?{?0?};
	Link(test4,?0,?1,?2);
	Link(test4,?1,?3,?4);
	Link(test4,?3,?5,?6);
	Link(test4,?5,?7,?-1);
	Link(test4,?6,?-1,?8);
	cout?<<?"test4:?"?<<?GetMaximumDistance(&test4[0]).nMaxDistance?<<?endl;
}
本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動力設(shè)備,其驅(qū)動電源的性能直接關(guān)系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護(hù)是驅(qū)動電源設(shè)計中至關(guān)重要的兩個環(huán)節(jié),集成化方案的設(shè)計成為提升電機(jī)驅(qū)動性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗。要解決這一問題,需從設(shè)計、生...

關(guān)鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術(shù)之一是電機(jī)驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動汽車的動力性能和...

關(guān)鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設(shè)計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關(guān)鍵字: LED 驅(qū)動電源 開關(guān)電源

LED驅(qū)動電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動電源
關(guān)閉