紅黑樹的實現與驗證 C

2021-08-16 08:42:43 字數 3954 閱讀 1916



紅黑樹的實現與驗證--c++

紅黑樹例項:

在說紅黑樹之前,我們先來認識一下它:

首先強調一點:紅黑樹也是二叉搜尋樹。那麼它就滿足二叉搜尋樹的性質,除此之外,他還有幾個比較特殊的性質,了解這些,有助於我們後面的分析

性質:1、紅黑樹所有的節點都有顏色(紅或黑)

2、紅黑樹的根結點是黑色的

3、紅黑樹的兩個紅色節點不能相連

4、紅黑樹的每一條鏈的黑節點的個數相同

5、所有空的節點都是黑色的

知道了這些之後開始進入紅黑樹的建立:

顯然這就是紅黑樹的插入操作的編寫了,那麼要想將乙個節點插入紅黑樹中,首先你得判斷紅黑樹是不是空的,如果是空的,那麼直接就可以插入;不是空的,那麼得找插入位置,然後再插入,這一點和二叉搜尋樹的插入是一樣的。不過需要注意,最後把根結點置成黑色的

插入?

插入的節點我們都預設為紅色的,但是性質3說,紅色的節點不能相鏈,如果,之後我們不管的話,性質3肯定不會滿足的,所以我們需要對紅黑樹進行調解,讓其滿足這些性質。那麼我們就需要分情況討論了,我們重點分析一下,兩個紅色節點相鏈的情況怎麼處理。

總共可以分為3種情況:

情況一:

雙親結點為紅色,祖先結點為黑色,叔叔節點存在,且為紅色

其實這個圖里包含了四種情況,我只是將其中的一種情況中的轉化後的形式畫了出來,其他的也一樣。

情況二:

雙親結點為紅色,祖先結點為黑色,叔叔節點不存在或存在為黑色

這種情況是:雙親在祖先節點的左的同時pcur在雙親的左;或是雙親在祖先節點的右的同時,pcur在雙親的右。

這樣我們就可以進行單旋處理,根據情況呼叫左單旋還是右單旋。

情況三:

雙親結點為紅色,祖先結點為黑色,叔叔節點不存在或存在為黑色

這個和情況二是互補的,情況二中剩下的都是不能單旋直接處理的,那麼就需要雙旋,圖中畫的是左右雙旋,先左旋之後,我們發現,和情況二的一樣,那麼**中這一塊就可以放在一起處理。

不過,這裡需要注意一點,就是,左旋之後只想pcur變成了雙親,而parent變成了孩子,所以,在第一次旋轉之後先對這兩個指標進行交換,在進行第二次旋轉。

驗證?

最後將插入寫完之後,我們可以寫乙個函式來測試一下這個是不是紅黑樹,這個其實也是對紅黑樹的性質的檢驗。其中重點驗證性質3和性質4。那麼我們來分析一下這步驟:

1、判斷這個樹是不是空樹,是的話,直接返回true

2、驗證性質2,判斷根結點的顏色是不是黑色的,是,返回true

3、要驗證性質三,得遍歷整個樹,而性質4的驗證也要這莫做,那麼我們將這兩個一起驗證。那麼首先我們得求出一條鏈的黑色節點的個數,並將其儲存起來,再遞迴遍歷左右子樹,驗證。

**?

#includeusing namespace std;

enum color ;

templatestruct rbtreenode

};templateclass rbtree

bool insert(const k& key, const v&value);

void _rotatel(node* parent);

void _rotater(node* parent);

void inorder();

void _inorder(node* proot);

bool checkrbtree();

bool _checkrbtree(node* proot,int counter,int k);

};//插入節點

templatebool rbtree::insert(const k&key, const v&value)

//尋找插入位置

node* pcur = _proot;

node* parent = null;

while (pcur)

else if (key > pcur->_key)

else

return false;

} //插入

pcur = new node(key, value);

if (key < parent->_key)

parent->_pleft = pcur;

else

parent->_pright = pcur;

pcur->_pparent = parent; //注意

//看紅黑樹是否滿足性質,分情況討論

while (_proot != pcur&&pcur->_pparent->_color == red)

else //情況二,三(將三轉化為二,再一起處理)

gf->_color = red;

parent->_color = black;

_rotater(gf);

}} else//雙親在右

else //情況

二、三(將情況三轉化為情況二,再一起處理)

gf->_color = red;

parent->_color = black;

_rotatel(gf);

}} }

_proot->_color = black;

return true;

}//左旋

templatevoid rbtree::_rotatel(node* parent)

//右旋

templatevoid rbtree::_rotater(node* parent)

templatevoid rbtree::inorder()

templatevoid rbtree::_inorder(node* proot)

}templatebool rbtree::checkrbtree()

//驗證性質4「每條鏈上的黑色結點都相等」,驗證性質3「紅色結點不能相連」

return _checkrbtree(_proot, blackcount, 0);

}templatebool rbtree::_checkrbtree(node* proot, int counter, int k)

return _checkrbtree(proot->_pleft, counter, k)

&& _checkrbtree(proot->_pright, counter, k);

}void testrbtree()

; //int a = ;

//int a = ;

rbtreet;

cout << "notorder: ";

for (int index = 0; index < sizeof(a) / sizeof(a[0]); index++)

cout << endl;

t.inorder();

if (t.checkrbtree())

cout << "是紅黑樹!" << endl;

else

cout << "不是紅黑樹!" << endl;

}int main()

紅黑樹(c實現)

學習紅黑樹原理,網路上有很多文章。學習紅黑樹的具體實現,個人推薦去看jdk中的treemap原始碼。因為該原始碼很簡潔,並且很容易改為其它語言的實現,最重要的是該份實現得到世人的認可,可以保證是沒問題的 下面是我根據其實現,使用c語言改寫的紅黑樹實現,目前只有紅黑樹的插入實現。include inc...

紅黑樹C 實現

完整實現了一遍紅黑樹,程式就當作自己的筆記好了 紅黑樹,顧名思義,就是紅黑相間的樹,它借由紅黑規則實現了二叉排序樹的平衡。紅黑規則如下 1.每個節點不是紅就是黑 2.根總是黑色 3.若節點為紅色,它的子節點必須為黑色 4.從根到葉的每條路徑,必須包含相同數目的黑色節點 插入和刪除節點時都要遵循紅黑規...

紅黑樹的C 實現

ifndef rbtree h define rbtree h include using namespace std define red 0 define black 1 template typename t class treenode treenode t value constructo...