日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

红黑树—BTree

發(fā)布時間:2024/4/11 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 红黑树—BTree 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

什么叫紅黑樹?

同AVL樹一樣,紅黑樹也是近似平衡的二叉搜索樹,與AVL樹不同的是紅黑樹沒有了平衡因子,但增加了一個枚舉變量,來標(biāo)明結(jié)點(diǎn)的顏(RED or BLACK)。因?yàn)榧t黑樹可以保證它的最長路勁不超過它最短路徑的兩倍,所以它近似平衡。

紅黑樹具有以下幾點(diǎn)性質(zhì):?
1. 每個結(jié)點(diǎn)都必須具有一種顏色(RED or BLACK)。?
2. 根結(jié)點(diǎn)為黑色。?
3. 如果一個結(jié)點(diǎn)為紅色,那么它的兩個孩子結(jié)點(diǎn)均為黑色(沒有連續(xù)的紅結(jié)點(diǎn))。?
4. 對于每個結(jié)點(diǎn),該結(jié)點(diǎn)到其所有后代葉子結(jié)點(diǎn)的路徑上,黑色結(jié)點(diǎn)的數(shù)量相同。?
5. 每個空結(jié)點(diǎn)(NIL結(jié)點(diǎn))都當(dāng)作一個黑色結(jié)點(diǎn)。

下圖為一棵簡單的紅黑樹:?

如何去創(chuàng)建并維護(hù)一棵紅黑樹?

紅黑樹的難點(diǎn)與AVL樹相同,插入一個結(jié)點(diǎn)并不難,難點(diǎn)在于插入一個結(jié)點(diǎn)后,很容易破壞這棵樹的平衡,我們就需要做一些調(diào)整工作讓這棵樹恢復(fù)平衡 。?
那么什么時候需要我們做調(diào)整工作呢?看上面紅黑樹性質(zhì)第三點(diǎn),一棵紅黑樹需要滿足沒有連續(xù)的紅結(jié)點(diǎn)。?
需要調(diào)整的兩種情況:?
1. 當(dāng)我們對一個紅結(jié)點(diǎn)下插入一個紅結(jié)點(diǎn)時,出現(xiàn)了連續(xù)的紅結(jié)點(diǎn)。調(diào)整。?
2. 調(diào)整需要改變結(jié)點(diǎn)的顏色,當(dāng)我們把一個黑結(jié)點(diǎn)變?yōu)榧t結(jié)點(diǎn),而恰好這個結(jié)點(diǎn)的父親是一個紅結(jié)點(diǎn)。又出現(xiàn)了連續(xù)的紅結(jié)點(diǎn)。繼續(xù)調(diào)整。

同時,性質(zhì)第4點(diǎn)也很重要, 對于每個結(jié)點(diǎn),該結(jié)點(diǎn)到其所有后代葉子結(jié)點(diǎn)的路徑上,黑色結(jié)點(diǎn)的數(shù)量相同。當(dāng)我們對一棵子樹進(jìn)行調(diào)整,這棵子樹也可能擁有一棵兄弟子樹,所以我們不能改變當(dāng)前子樹上黑色節(jié)點(diǎn)的數(shù)量,即路徑上黑結(jié)點(diǎn)的數(shù)量不能改變。?
總結(jié)下來,調(diào)整方案就是:遇到連續(xù)紅結(jié)點(diǎn)就調(diào)整,調(diào)整的同時要保證路徑上黑色節(jié)點(diǎn)的數(shù)量不變。

PS:①在下面的講解中會改變結(jié)點(diǎn)的顏色,當(dāng)我們遇到連續(xù)的紅結(jié)點(diǎn)并進(jìn)行調(diào)整時,我們并不知道這個紅結(jié)點(diǎn)怎么來的,可能是新插入的,也可能是之前的調(diào)整由黑結(jié)點(diǎn)變過來的。②叔叔結(jié)點(diǎn)(uncle)。③a、b、c、d、e均為子樹,若一個為空,則都為空,此時cur為新插入結(jié)點(diǎn)。若不為空,則都不為空,此時cur為被調(diào)整改變的結(jié)點(diǎn)。注意這個三個概念,會幫助我們理解下面的講解。

插入情況1:

當(dāng)前結(jié)點(diǎn)cur為紅,父親結(jié)點(diǎn)parent為紅,gparent為黑,叔叔結(jié)點(diǎn)uncle存在且為紅。?
①?
?
②?

這種情況我們只需要改變結(jié)點(diǎn)顏色,不需要挪動結(jié)點(diǎn)位置。?
顏色調(diào)整:將parent與叔叔結(jié)點(diǎn)uncle的顏色變?yōu)楹谏?#xff0c;將gparent的顏色變?yōu)榧t色。?
繼續(xù)向上調(diào)整:令cur = gparent,parent = gparent->_parent。繼續(xù)向上調(diào)整。

代碼

uncle->_col = parent->_col = BLACK; Gparent->_col = RED;// Gparent 可能為子樹,保證黑色節(jié)點(diǎn)數(shù)量不變//繼續(xù)向上調(diào)整 cur = Gparent; parent = cur->_parent;

插入情況2:

當(dāng)前結(jié)點(diǎn)cur為紅色,parent為紅色,gparent為紅色,叔叔結(jié)點(diǎn)uncle不存在或者為黑。(ps:當(dāng)uncle結(jié)點(diǎn)不存在時,所有子樹都不存在,cur為新插入結(jié)點(diǎn),當(dāng)uncle存在且為黑時,cur為被調(diào)整改變的結(jié)點(diǎn)。以下我們以uncle存在且為黑為例。)

這個情況又可分為兩種小情況:?
① parent為gparent的左孩子,cur為parent的左孩子。?
?
這種情況需要對gparent進(jìn)行右單旋操作,看過之前我寫的AVL樹講解的朋友們相信已經(jīng)對旋轉(zhuǎn)操作不再陌生了,這里我再講一下。?
旋轉(zhuǎn)操作:將parent的右子樹變成gparent的左子樹,將gparent以及其子樹變成parent的右子樹。將gparent的父親結(jié)點(diǎn)指向parent。?
顏色調(diào)整:將parent的顏色變成黑色,將gparent的顏色變成紅色。?
繼續(xù)向上調(diào)整:令cur = parnet, parent = parent->_parnet.

代碼:

void RotateR(Node* parent) {Node* SubL = parent->_left;Node* SubLR = SubL->_right;parent->_left = SubLR;if (SubLR){SubLR->_parent = parent;}Node* ppNode = parent->_parent;SubL->_right = parent;parent->_parent = SubL;if (ppNode){if (ppNode->_left == parent)ppNode->_left = SubL;elseppNode->_right = SubL;SubL->_parent = ppNode;}else{SubL->_parent = NULL;_root = SubL;} }

② parent為gparent的右孩子,cur為parent的右孩子。?
?
這種情況需要對gparent進(jìn)行左單旋操作。?
旋轉(zhuǎn)操作:將parent 的左子樹變?yōu)間parent的右子樹,將gparent以及其子樹變成parent的左子樹,將gparnet的父親結(jié)點(diǎn)指向parent。?
顏色調(diào)整:將parent變?yōu)楹谏?#xff0c;將gparent變?yōu)榧t色。?
繼續(xù)向上調(diào)整:令cur = parent,parent = parent->_parent。

代碼

void RotateL(Node* parent) {Node* SubR = parent->_right;Node* SubRL = SubR->_left;parent->_right = SubRL;if (SubRL){SubRL->_parent = parent;}Node* ppNode = parent->_parent;SubR->_left = parent;parent->_parent = SubR;if (ppNode){if (ppNode->_left == parent)ppNode->_left = SubR;elseppNode->_right = SubR;SubR->_parent = ppNode;}else{SubR->_parent = NULL;_root = SubR;} }

插入情況3:

當(dāng)前節(jié)點(diǎn)cur為紅色,parent為紅色,gparent為黑色。叔叔uncle結(jié)點(diǎn)不存在或?yàn)楹?ps:當(dāng)uncle結(jié)點(diǎn)不存在時,所有子樹都不存在,cur為新插入結(jié)點(diǎn),當(dāng)uncle存在且為黑時,cur為被調(diào)整改變的結(jié)點(diǎn)。以下我們以uncle存在且為黑為例。)

這種情況也可分成兩種:?
①parent為gparent左孩子,cur為parent右孩子。?
?
這種情況需要先對parent進(jìn)行左單旋操作,轉(zhuǎn)換為情況2的第①種情況。?
再進(jìn)行情況2的①操作。注意:左單旋之后,parent指針指向的位置,與cur指針指向的位置已經(jīng)改變。再進(jìn)行情況2的②操作之前需要交換parent與cur指針。調(diào)用swap函數(shù)swap(parent,cur)。

代碼:

if (cur == parent->_right) {RotateL(parent);swap(parent, cur);//保證parent指針?biāo)赶虻奈恢貌蛔?/span> } RotateR(Gparent);//保證左右子樹的黑色節(jié)點(diǎn)數(shù)量不變 parent->_col = BLACK; Gparent->_col = RED; //繼續(xù)向上調(diào)整cur = parent; parent = cur->_parent;

②parent為gparent右孩子,cur為parent左孩子。?
?
這種情況需要先對parent進(jìn)行右單旋操作,轉(zhuǎn)換為情況2的第②種情況。?
再進(jìn)行情況2的②操作。同上,交換parent與cur指針。調(diào)用swap函數(shù)swap(parent,cur)。

代碼

if (cur == parent->_left) {RotateR(parent);swap(parent, cur); } RotateL(Gparent);parent->_col = BLACK; Gparent->_col = RED;cur = parent; parent = cur->_parent;

總結(jié)?
紅黑樹與AVL樹都是高效的平衡二叉樹,增刪查改時間復(fù)雜的都為O(lgN),但是紅黑樹并不追求完全平衡,可以保證最長路徑不超過最短路徑的2倍,相對而言,降低了旋轉(zhuǎn)要求,性能相對優(yōu)于AVL樹,所以實(shí)際運(yùn)用中紅黑樹運(yùn)用較多。

完整代碼

頭文件 RBTree.h

#pragma once #include<iostream> using namespace std;enum Colour {RED,BLACK };template<typename K,typename V> struct RBTreeNode {K _key;V _value;RBTreeNode<K, V>* _left;RBTreeNode<K, V>* _right;RBTreeNode<K, V>* _parent;Colour _col;RBTreeNode(const K& key, const V& value):_key(key), _value(value), _left(NULL), _right(NULL), _parent(NULL), _col(RED){} };template<typename K, typename V> class RBTree {typedef RBTreeNode<K, V> Node; public:RBTree():_root(NULL){}bool Insert(const K& key,const V& value){if (_root == NULL){_root = new Node(key, value);_root->_col = BLACK;return true;}Node* cur = _root;Node* parent = cur;while (cur){if (key > cur->_key){parent = cur;cur = cur->_right;}else if (key < cur->_key){parent = cur;cur = cur->_left;}else{return false;}}cur = new Node(key, value);if (key > parent->_key){parent->_right = cur;cur->_parent = parent;}else{parent->_left = cur;cur->_parent = parent;}//調(diào)整//parent肯定不為空//如果parent為黑色,則不用調(diào)整while (cur != _root && parent->_col == RED)//保證下一次循環(huán)parent不為空{Node* Gparent = parent->_parent;if (parent == Gparent->_left){//判斷叔叔節(jié)點(diǎn)的顏色//叔叔節(jié)點(diǎn)為RED//叔叔節(jié)點(diǎn)為BLACK或者不存在Node* uncle = Gparent->_right;if (uncle && uncle->_col == RED)//叔叔節(jié)點(diǎn)為RED{uncle->_col = parent->_col = BLACK;Gparent->_col = RED;// Gparent 可能為子樹,保證黑色節(jié)點(diǎn)數(shù)量不變//繼續(xù)向上調(diào)整cur = Gparent;parent = cur->_parent;}else//叔叔節(jié)點(diǎn)為BLACK或者不存在{if (cur == parent->_right){RotateL(parent);swap(parent, cur);//保證parent指針?biāo)赶虻奈恢貌蛔?/span>}RotateR(Gparent);//保證左右子樹的黑色節(jié)點(diǎn)數(shù)量不變parent->_col = BLACK;Gparent->_col = RED;//繼續(xù)向上調(diào)整cur = parent;parent = cur->_parent;}}else{Node* uncle = Gparent->_left;if (uncle && uncle->_col == RED){uncle->_col = parent->_col = BLACK;Gparent->_col = RED;cur = Gparent;parent = cur->_parent;}else{if (cur == parent->_left){RotateR(parent);swap(parent, cur);}RotateL(Gparent);parent->_col = BLACK;Gparent->_col = RED;cur = parent;parent = cur->_parent;}}}_root->_col = BLACK;return true;}void InOrder(){_InOrder(_root);cout << endl;}bool IsRBTree(){if (_root == NULL){return true;}if (_root->_col == RED){return false;}Node* cur = _root;size_t count = 0;while (cur){if (cur->_col == BLACK)count++;cur = cur->_left;}size_t k = 0;return _IsRBTree(_root, count, k++);} protected:void RotateL(Node* parent){Node* SubR = parent->_right;Node* SubRL = SubR->_left;parent->_right = SubRL;if (SubRL){SubRL->_parent = parent;}Node* ppNode = parent->_parent;SubR->_left = parent;parent->_parent = SubR;if (ppNode){if (ppNode->_left == parent)ppNode->_left = SubR;elseppNode->_right = SubR;SubR->_parent = ppNode;}else{SubR->_parent = NULL;_root = SubR;}}void RotateR(Node* parent){Node* SubL = parent->_left;Node* SubLR = SubL->_right;parent->_left = SubLR;if (SubLR){SubLR->_parent = parent;}Node* ppNode = parent->_parent;SubL->_right = parent;parent->_parent = SubL;if (ppNode){if (ppNode->_left == parent)ppNode->_left = SubL;elseppNode->_right = SubL;SubL->_parent = ppNode;}else{SubL->_parent = NULL;_root = SubL;}}void _InOrder(Node* root){if (root == NULL){return;}_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);}bool _IsRBTree(Node* root, const size_t& count, size_t k){if (root == NULL){return count == k;}Node * parent = root->_parent;if (parent && parent->_col == RED && root->_col == RED){return false;}if (root->_col == BLACK){k++;}return _IsRBTree(root->_left, count, k) && _IsRBTree(root->_right, count, k);} protected:Node* _root; };void TestRBTree() {RBTree<int, int> tree;int a[9] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };for (int i = 0; i < 9; i++){tree.Insert(a[i], i);cout << tree.IsRBTree() <<"->"<<a[i]<< endl;}tree.InOrder();cout << tree.IsRBTree() << endl; }

test.cpp

#include"RBTree.h"int main() {TestRBTree();system("pause");return 0; }

總結(jié)

以上是生活随笔為你收集整理的红黑树—BTree的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲欧美自拍视频 | 久久久性色精品国产免费观看 | jizz欧美性20 | 污污视频在线看 | 欧美日韩视频一区二区三区 | 一级国产黄色片 | 黄色片网站视频 | 在线观看日韩一区 | 在线精品视频一区 | 欧美在线国产 | 国产色无码精品视频 | 国产伦理精品 | 91丨九色丨丰满人妖 | 播放男人添女人下边视频 | 中文字幕色哟哟 | 精品一区李梓熙捆绑 | 男ji大巴进入女人的视频 | 蜜桃av免费在线观看 | 亚洲熟女少妇一区二区 | 小毛片 | 亚洲欧美精品一区二区 | 欧美激情在线观看一区 | 久久网中文字幕 | 久久国产露脸精品国产 | 国产xxxx视频 | 成人免费在线观看av | 国产福利短视频 | 伊人称影院| 国产熟女一区二区三区五月婷 | 日本一区二区三区在线免费观看 | 特黄一区 | 搞黄网站在线观看 | 麻豆精品在线视频 | 456亚洲影视 | 国产xxxxx视频 | 天天干天天干天天操 | 激情丁香网 | 青青视频免费看 | 在线观看中文字幕 | jizz高潮| 日韩欧美视频免费在线观看 | 国产精品电影在线观看 | 16—17女人毛片 | 男人天堂资源网 | 全部免费毛片 | 天天摸天天插 | 成人爱爱视频 | av在线网址大全 | 天天射干 | 免费毛片网站在线观看 | 日批视频免费看 | 国产一区二区黄色 | 玖玖综合网 | 中文字幕第22页 | av生活片| 在线观看欧美精品 | 海角国产乱辈乱精品视频 | jizzjizzjizz亚洲女 | 国产精品第八页 | 亚洲一区二区日本 | a免费观看 | 456av| 国产精品久久久久久久久久 | 丰满圆润老女人hd | 日韩精品一区二区三区无码专区 | 国产毛片久久久久 | 97视频资源 | 伊人久久久久久久久 | 黄色国产毛片 | 日美一级片| cekc老妇女cea0| 国产视频99 | 一个色在线视频 | 色呦呦官网| 欧美黄视频| 国产激情一区二区三区四区 | 国产免费视频 | 成人xxx| 亚洲一级在线播放 | 久久久久玖玖 | 欧美色综合色 | 国产一区二区毛片 | 国产三区av | 亚洲国产成人精品一区二区三区 | 色哟哟在线视频 | 国产精品成人Av | 亚洲av无码一区二区三区在线播放 | 日韩小视频网站 | 人妻丰满熟妇av无码区 | 99re最新网址 | 国产麻豆剧传媒精品国产av | 都市激情校园春色 | 美女毛片视频 | 国产免费a| 国产亚洲精品美女久久久 | 天天久久综合 | a级黄色一级片 | 免费一级特黄特色大片 | 中文字幕精品视频 |