女人被狂躁到高潮视频免费无遮挡,内射人妻骚骚骚,免费人成小说在线观看网站,九九影院午夜理论片少妇,免费av永久免费网址

當前位置:首頁 > > 充電吧
[導讀]linux內(nèi)存管理模塊中使用紅黑樹算法來提升虛擬內(nèi)存查找速度,源碼請參考linux內(nèi)核目錄下rbtree.c文件。紅黑樹算法原理在閱讀紅黑樹算法源代碼之前最好先了解紅黑樹原理。rb_insert_co

linux內(nèi)存管理模塊中使用紅黑樹算法來提升虛擬內(nèi)存查找速度,源碼請參考linux內(nèi)核目錄下rbtree.c文件。

紅黑樹算法原理

在閱讀紅黑樹算法源代碼之前最好先了解紅黑樹原理。

rb_insert_color函數(shù)詳解:

void?rb_insert_color(rb_node_t?*?node,?rb_root_t?*?root)
{
	rb_node_t?*?parent,?*?gparent;

	while?((parent?=?node->rb_parent)?&&?parent->rb_color?==?RB_RED)
	{
		gparent?=?parent->rb_parent;

		if?(parent?==?gparent->rb_left)
		{
			{
				register?rb_node_t?*?uncle?=?gparent->rb_right;
				if?(uncle?&&?uncle->rb_color?==?RB_RED)
				{
					uncle->rb_color?=?RB_BLACK;
					parent->rb_color?=?RB_BLACK;
					gparent->rb_color?=?RB_RED;
					node?=?gparent;
					continue;
				}
			}

			if?(parent->rb_right?==?node)
			{
				register?rb_node_t?*?tmp;
				__rb_rotate_left(parent,?root);
				tmp?=?parent;
				parent?=?node;
				node?=?tmp;
			}

			parent->rb_color?=?RB_BLACK;
			gparent->rb_color?=?RB_RED;
			__rb_rotate_right(gparent,?root);
		}?else?{
			{
				register?rb_node_t?*?uncle?=?gparent->rb_left;
				if?(uncle?&&?uncle->rb_color?==?RB_RED)
				{
					uncle->rb_color?=?RB_BLACK;
					parent->rb_color?=?RB_BLACK;
					gparent->rb_color?=?RB_RED;
					node?=?gparent;
					continue;
				}
			}

			if?(parent->rb_left?==?node)
			{
				register?rb_node_t?*?tmp;
				__rb_rotate_right(parent,?root);
				tmp?=?parent;
				parent?=?node;
				node?=?tmp;
			}

			parent->rb_color?=?RB_BLACK;
			gparent->rb_color?=?RB_RED;
			__rb_rotate_left(gparent,?root);
		}
	}

	root->rb_node->rb_color?=?RB_BLACK;
}

注解:

??? 函數(shù)參數(shù)

??????? node:新插入的結(jié)點。

??????? root:紅黑樹的根結(jié)點。

??? 第5行:往紅黑樹中插入結(jié)點時,總是將新插入結(jié)點顏色設(shè)置為紅色。當新結(jié)點的父結(jié)點不存在或者父結(jié)點顏色為黑色時,不需要做紅黑樹調(diào)整直接跳到第63行。

??? 第7行:獲取node結(jié)點的祖父結(jié)點。

??? (第9-35行 處理node父結(jié)點是其祖父結(jié)點左子結(jié)點的情況)

??? 第12行:獲取node的叔父結(jié)點。

??? 第13-20行:當叔父結(jié)點存在并且顏色為紅色,就將node的父結(jié)點與叔父結(jié)點的顏色設(shè)成黑色,并且將node的祖父結(jié)點顏色設(shè)成紅色?,F(xiàn)在祖父結(jié)點的顏色為紅色,但祖父結(jié)點的父結(jié)點也可能為紅色,不滿足紅黑樹性質(zhì),因此將祖父結(jié)點當做新插入的結(jié)點重新進行紅黑樹調(diào)整。

??? 第23-30行:叔父結(jié)點不存在或者顏色為黑色,此時node的祖父結(jié)點顏色必為黑色(因為node父結(jié)點顏色為紅色),針對node的父結(jié)點進行一次左旋轉(zhuǎn),讓父結(jié)點成為node的左子結(jié)點,并交換父結(jié)點與node結(jié)點位置,使以前的父結(jié)點成為新插入的結(jié)點。

??? 第32-34得:將父結(jié)點的顏色設(shè)為黑色(此時新node的顏色還是紅色),將祖父結(jié)點的顏色設(shè)為紅色。再針對祖父結(jié)點進行一次右旋轉(zhuǎn),此時node擁有一個黑色的父結(jié)點及紅色的兄弟結(jié)點。

??? (第36-61行處理node的父結(jié)點是其祖父結(jié)點的右子結(jié)點的情況)

??? 第37行:獲取node的叔父結(jié)點。

??? 第38行:當node的叔父結(jié)點存在并且顏色為紅色,就將node的父結(jié)點與叔父結(jié)點設(shè)置為黑色,并將node的祖父結(jié)點設(shè)置為紅色。再將祖父結(jié)點當做新插入的結(jié)點重新進行紅黑樹調(diào)整。

??? 第48-55行:如果node結(jié)點是其父結(jié)點的左子結(jié)點,就針對node的父結(jié)點進行一次右旋轉(zhuǎn),讓其父結(jié)點成為node的右子結(jié)點,并交換父結(jié)點與node的位置,讓以前的父結(jié)點成為新插入的結(jié)點

??? 第57-59行:將父結(jié)點的顏色設(shè)為黑色(此時新node的顏色還是紅色),將祖父結(jié)點的顏色設(shè)置為紅色。再針對祖父結(jié)點進行一次左旋轉(zhuǎn),此時node擁有一個黑色的父結(jié)點及紅色的兄弟結(jié)點。

??? 第63行:將根結(jié)點的顏色設(shè)為黑色。這一步是有必要的,當新插入的結(jié)點為根結(jié)點或者在樹調(diào)整過程中將根結(jié)點顏色變成了紅色,這一行將根結(jié)點的顏色設(shè)成黑色。

?rb_erase函數(shù)詳解:

void?rb_erase(rb_node_t?*?node,?rb_root_t?*?root)
{
	rb_node_t?*?child,?*?parent;
	int?color;

	if?(!node->rb_left)
		child?=?node->rb_right;
	else?if?(!node->rb_right)
		child?=?node->rb_left;
	else
	{
		rb_node_t?*?old?=?node,?*?left;

		node?=?node->rb_right;
		while?((left?=?node->rb_left))
			node?=?left;
		child?=?node->rb_right;
		parent?=?node->rb_parent;
		color?=?node->rb_color;

		if?(child)
			child->rb_parent?=?parent;
		if?(parent)
		{
			if?(parent->rb_left?==?node)
				parent->rb_left?=?child;
			else
				parent->rb_right?=?child;
		}
		else
			root->rb_node?=?child;

		if?(node->rb_parent?==?old)
			parent?=?node;
		node->rb_parent?=?old->rb_parent;
		node->rb_color?=?old->rb_color;
		node->rb_right?=?old->rb_right;
		node->rb_left?=?old->rb_left;

		if?(old->rb_parent)
		{
			if?(old->rb_parent->rb_left?==?old)
				old->rb_parent->rb_left?=?node;
			else
				old->rb_parent->rb_right?=?node;
		}?else
			root->rb_node?=?node;

		old->rb_left->rb_parent?=?node;
		if?(old->rb_right)
			old->rb_right->rb_parent?=?node;
		goto?color;
	}

	parent?=?node->rb_parent;
	color?=?node->rb_color;

	if?(child)
		child->rb_parent?=?parent;
	if?(parent)
	{
		if?(parent->rb_left?==?node)
			parent->rb_left?=?child;
		else
			parent->rb_right?=?child;
	}
	else
		root->rb_node?=?child;

?color:
	if?(color?==?RB_BLACK)
		__rb_erase_color(child,?parent,?root);
}

注解:

??? 函數(shù)參數(shù):

? ? ? ??node: 將要刪除的結(jié)點

? ? ? ? root: 紅黑樹的根結(jié)點

??? (第6-9行處理被刪結(jié)點至多只有一個子結(jié)點的情況,并找出不為空的子結(jié)點)

? ? 第6-7行:判斷node的左子結(jié)點是否存在,如果不存在child針指就指向右子結(jié)點(右子結(jié)點也可能不存在)。

??? 第8-9行:判斷node的右子結(jié)點是否存在,如果不存在child指針就指向其左子結(jié)點。

??? (第11-53行 處理被刪結(jié)點有兩個非空子結(jié)點的情況。當結(jié)點存在兩個非空子結(jié)點時就找出其左子樹中元素最大的結(jié)點或者右子樹中元素最小的結(jié)點,并將該結(jié)點替換到將要被刪除的結(jié)點位置上,再刪除元素最大或者最小的結(jié)點。這時就將刪除有兩個非空子結(jié)點的問題變成刪除至多只有一個非空子結(jié)點的問題。linux內(nèi)存管理模塊中的紅黑樹是按結(jié)點所在的內(nèi)存首地址來排序存儲的,如父結(jié)點的內(nèi)存首地址一定會大于其左子結(jié)點首地址且小于右子結(jié)點首地址,因此在替換結(jié)點時只替換結(jié)點的位置不能改變結(jié)點的首地址)。

??? 第12行:保存node到old變量中。

??? 第14-16行:找出node的右子樹中首地址最小的結(jié)點。如果找到就將該結(jié)點當做將要被刪除的結(jié)點。

??? 第17行:獲取node的右子結(jié)點,經(jīng)過第14-16行的處理現(xiàn)在node結(jié)點的首地址最小,所以node不可能存在左子結(jié)點,但右子結(jié)點可能會存在。

??? 第18行:獲取node的父結(jié)點。

??? 第19行:獲取node的顏色屬性。

??? 第21-22行:如果node的子結(jié)點存在,就設(shè)置其子結(jié)點的父結(jié)點為node的父結(jié)點(因為node結(jié)點將要被刪除)。

??? 第23-29行:如果node的父結(jié)點存在,當node是其父結(jié)點的左子結(jié)點時就設(shè)置node的子結(jié)點為其父結(jié)點的左子結(jié)點,否則就設(shè)置為其父結(jié)點的右子結(jié)點。

??? 第30-31行:這種情況不可能會發(fā)生。

??? 第33-34行:如果node等于old,說明old(old中保存有rb_erase函數(shù)中node參數(shù)的值,即要被替換的結(jié)點)的右子結(jié)點沒有子結(jié)點,將父結(jié)點指向node結(jié)點(當node等于old時,在node替換old之后,node與其子結(jié)點的關(guān)系保持不變)。

??? (第35-38行 這里將node結(jié)點替換掉old結(jié)點)

??? 第35行:設(shè)置node的父結(jié)點為old結(jié)點的父結(jié)點。

??? 第36行:將old結(jié)點顏色替換到node結(jié)點中。

??? 第37行:將node的右子結(jié)點設(shè)置為old的右子結(jié)點。

??? 第38行:將node的左子結(jié)點設(shè)置為old的左子結(jié)點。

??? 第40-46行:如果old的父結(jié)點存在,當old是其父結(jié)點的左子結(jié)點時就將node變成其父結(jié)點的左子結(jié)點,否則為其父結(jié)點的右子結(jié)點。

??? 第47行:如果old為根結(jié)點就設(shè)置node為根結(jié)點。

??? 第49行:將node設(shè)置為old左子結(jié)點的父結(jié)點。

??? 第50-51行:如果old的右子結(jié)點存在,設(shè)置node為old右子結(jié)點的父結(jié)點。

??? 第52行:跳轉(zhuǎn)到70行進一步處理。

??? (第55-68行 進一步處理被刪結(jié)點至多只有一個非空子結(jié)點的情況)

??? 第55-56行:獲取node的父結(jié)點及顏色。

??? 第58-59行:如果node的子結(jié)點存在,就設(shè)置其子結(jié)點的父結(jié)點為node的父結(jié)點。

??? 第60-66行:node的父結(jié)點存在且node是其父結(jié)點的左子結(jié)點時就設(shè)置node的子結(jié)點為父結(jié)點的左了結(jié)點,否則為父結(jié)點的右子結(jié)點。

??? 第67-68行:當node為根結(jié)點時,刪除node后,其子結(jié)點成為根結(jié)點。

??? 第70-72行:如果被刪結(jié)點顏色為紅色,此時不影響紅黑樹性質(zhì),否則調(diào)用__rb_erase_color函數(shù)進一步處理。

??? 當rb_erase函數(shù)刪除有兩個非空子結(jié)點的結(jié)點時比較復雜,難以理解。下面提供兩張刪除結(jié)點的示例圖便于理解,本想提供flash動畫的,但不知道怎么發(fā)到博客上來。

???? 示例1:假設(shè)被刪結(jié)點為父結(jié)點的左子結(jié)點,且被刪結(jié)點的右子結(jié)點沒有子結(jié)點

??? 示例2:假設(shè)被刪結(jié)點是父結(jié)點的右子結(jié)點,且被刪結(jié)點的右子結(jié)點存在兩個非空子結(jié)點

__rb_erase_color函數(shù)詳解:


static?void?__rb_erase_color(rb_node_t?*?node,?rb_node_t?*?parent,
			?????rb_root_t?*?root)
{
	rb_node_t?*?other;

	while?((!node?||?node->rb_color?==?RB_BLACK)?&&?node?!=?root->rb_node)
	{
		if?(parent->rb_left?==?node)
		{
			other?=?parent->rb_right;
			if?(other->rb_color?==?RB_RED)
			{
				other->rb_color?=?RB_BLACK;
				parent->rb_color?=?RB_RED;
				__rb_rotate_left(parent,?root);
				other?=?parent->rb_right;
			}
			if?((!other->rb_left?||
			?????other->rb_left->rb_color?==?RB_BLACK)
			????&&?(!other->rb_right?||
				other->rb_right->rb_color?==?RB_BLACK))
			{
				other->rb_color?=?RB_RED;
				node?=?parent;
				parent?=?node->rb_parent;
			}
			else
			{
				if?(!other->rb_right?||
				????other->rb_right->rb_color?==?RB_BLACK)
				{
					register?rb_node_t?*?o_left;
					if?((o_left?=?other->rb_left))
						o_left->rb_color?=?RB_BLACK;
					other->rb_color?=?RB_RED;
					__rb_rotate_right(other,?root);
					other?=?parent->rb_right;
				}
				other->rb_color?=?parent->rb_color;
				parent->rb_color?=?RB_BLACK;
				if?(other->rb_right)
					other->rb_right->rb_color?=?RB_BLACK;
				__rb_rotate_left(parent,?root);
				node?=?root->rb_node;
				break;
			}
		}
		else
		{
			other?=?parent->rb_left;
			if?(other->rb_color?==?RB_RED)
			{
				other->rb_color?=?RB_BLACK;
				parent->rb_color?=?RB_RED;
				__rb_rotate_right(parent,?root);
				other?=?parent->rb_left;
			}
			if?((!other->rb_left?||
			?????other->rb_left->rb_color?==?RB_BLACK)
			????&&?(!other->rb_right?||
				other->rb_right->rb_color?==?RB_BLACK))
			{
				other->rb_color?=?RB_RED;
				node?=?parent;
				parent?=?node->rb_parent;
			}
			else
			{
				if?(!other->rb_left?||
				????other->rb_left->rb_color?==?RB_BLACK)
				{
					register?rb_node_t?*?o_right;
					if?((o_right?=?other->rb_right))
						o_right->rb_color?=?RB_BLACK;
					other->rb_color?=?RB_RED;
					__rb_rotate_left(other,?root);
					other?=?parent->rb_left;
				}
				other->rb_color?=?parent->rb_color;
				parent->rb_color?=?RB_BLACK;
				if?(other->rb_left)
					other->rb_left->rb_color?=?RB_BLACK;
				__rb_rotate_right(parent,?root);
				node?=?root->rb_node;
				break;
			}
		}
	}
	if?(node)
		node->rb_color?=?RB_BLACK;
}

注解:

??? 函數(shù)參數(shù):

??????? node:被刪結(jié)點的子結(jié)點

??????? parent:被刪結(jié)點的父結(jié)點

??????? root:紅黑樹根結(jié)點

??? 第6行:如果node是根結(jié)點或者其顏色為紅色while循環(huán)結(jié)束(調(diào)用__rb_erase_color函數(shù)的條件是被刪結(jié)點顏色為黑色,直接將被刪結(jié)點的子結(jié)點node置為黑色就滿足紅黑樹性質(zhì))。

??? (第8-47行 處理node是其父結(jié)點的左子結(jié)點情況)

??? 第10行:獲取node的兄弟結(jié)點,保存到other變量中。

??? 第11-17行:當other結(jié)點顏色為紅色時(other父結(jié)點顏色必為黑),將其父結(jié)點置為紅色,other結(jié)點置為黑色。并針對其父結(jié)點進行一次左旋轉(zhuǎn)讓other的父結(jié)點成為它的左子結(jié)點(此種情況的詳細步驟請參考上面提起過的紅黑樹原理網(wǎng)站中刪除結(jié)點的情況2),并從新獲取node的兄弟結(jié)點。

??? 第18-26行:如果other的兩個子結(jié)點都為黑色,這時就將other置為紅色。重新在node的父結(jié)點上做紅黑樹調(diào)整(參考紅黑樹原理網(wǎng)站中刪除結(jié)點的情況4)。

??? (第28-46行 處理other的子結(jié)點顏色為紅色的情況)

??? 第29-38行:當other的右子結(jié)點為黑色時(此時other的左子結(jié)點必為紅色),將other的左子結(jié)點置為黑色,other置為紅色并針對other進行一次右旋轉(zhuǎn),使other的左子結(jié)點成為other的父結(jié)點(參考紅黑樹原理網(wǎng)站中刪除結(jié)點的情況5),重新獲取node的兄弟結(jié)點,保存到other變量中。

??? 第39-44行:設(shè)置other的顏色為其父結(jié)點的顏色,將父結(jié)點的顏色置為黑色,設(shè)置other的右子結(jié)點顏色為黑色并針對node的父結(jié)點進行一次左旋轉(zhuǎn)(參考紅黑樹原理網(wǎng)站中刪除結(jié)點的情況6)。

??? 第49-87行:這里的處理步驟與8-47行類似。

??? 第89-90行:將根結(jié)點置為黑色。

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

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

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

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

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

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

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

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

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

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

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

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(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)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

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

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

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