紅黑樹(演算法導論)

2021-06-25 12:13:43 字數 3611 閱讀 1089

測試**所用的例子為算導第三版p179圖13-4

#include using namespace std;

const bool black = 0; // 黑色

const bool red = 1; // 紅色

struct node // 結點結構

};class rb_tree

// 初始化nil結點和root

node *left_rotate(node *x); // 左旋

node *right_rotate(node *x); // 右旋

void rb_insert(node *z); // 插入乙個結點

void rb_insert_fixup(node *z); // 插入後調整

node *tree_minimum(node *x); // 找最小值

node *tree_successor(node *x); // 找到x的後繼

node *rb_search(node *x, int k); // 查詢元素

node *rb_delete(node *z); // 刪除乙個結點

void rb_delete_fixup(node *x); // 刪除後調整

void rb_print(node *x);

void print();// 輸出

};node *rb_tree::left_rotate(node *x) // 先將y的左孩子變為x的右孩子(y有做孩子的話)

y->parent = x->parent;

if (x->parent == nil)

else if (x->parent->left == x)

else

y->left = x;

x->parent = y;

return y;

}node *rb_tree::right_rotate(node *x) // y的右孩子成為x的左孩子 y成為x父親的孩子 x成為y的右孩子

y->parent = x->parent;

if (x->parent == nil)

if (x->parent->right == x)

else

y->right = x;

x->parent = y;

return y;

}void rb_tree::rb_insert(node *z)

else

}// 將 z插入到y的合適部位

z->parent = y;

if (y == nil) // 樹空的時候 z成為根結點

else if (z->key < y->key)

else

// 調整先插入的z的屬性 然後調整 保持樹的性質

z->left = nil;

z->right = nil;

z->color = red; // 必須為紅 黑的話 會破壞樹的性質

rb_insert_fixup(z); // 向上調整維護樹的性質

}void rb_tree::rb_insert_fixup(node *z)

else // case 2 z的叔節點黑色且z是右孩子

z->parent->color = black; // case 3 z的叔節點是黑色的且z是左孩子

z->parent->parent->color = red;

right_rotate(z->parent->parent);

}} else if (z->parent == z->parent->parent->right) // p[z]為右孩子的時候 與上面對稱

else

z->parent->color = black;

z->parent->parent->color = red;

left_rotate(z->parent->parent);

}} }

root->color = black; // 根結點調整為黑色

}node *rb_tree::tree_minimum(node *x) // 求最小值

return x;

}node *rb_tree::tree_successor(node *x) // 尋找元素的後繼

node *y = x->parent; // 一直向上尋找

while (y != nil && x == y->right)

return y;

}node *rb_tree::rb_search(node *x, int k) // 尋找某個元素

if (k < x->key)

else }

node *rb_tree::rb_delete(node *z) // 刪除某個元素 與bst基本一樣

else if (y == y->parent->left)

else

if (y != z)

if (y->color == black) // 如果刪除的是黑色結點 則向上調整樹的性質 刪除的是紅色的什麼也不影響 直接刪掉即可

return y;

}void rb_tree::rb_delete_fixup(node *x) // 假設刪除的y的黑色給了x x有了兩層黑色這樣可以滿足性質5 只需要調整性質1 2 4即可

if (w->left->color == black && w->right->color == black) // case 2

else

w->color = x->parent->color; // case 4

x->parent->color = black;

w->right->color = black;

left_rotate(x->parent);

x = root;

}} else if (x == x->parent->right) // x是右孩子的是 與上面對稱的過程

if (w->right->color == black && w->left->color == black)

else

w->color = x->parent->color;

x->parent->color = black;

w->left->color = black;

right_rotate(x->parent);

x = root;

}} }

x->color = black; // 目的是把新結點染為單一黑色

}void rb_tree::rb_print(node *x)

rb_print(x->left);

cout << x->key << " " << x->color << endl;

rb_print(x->right);

}void rb_tree::print() // 中序遍歷樹 全部輸出

int main()

; for (int i = 0; i < 9; ++i)

cout << (*(t.root)).key << endl;

t.rb_delete(t.root);

cout << endl;

t.print();

return 0;

}

演算法導論 紅黑樹

原文 組內培訓,講紅黑樹,找出演算法導論,啃了乙個週末,其中插入結點很簡單,刪除結點有點複雜,但跟著演算法導論上一步一步來沒有什麼問題。不想備份blog的,所以沒有把上穿。可直接察看ppt。紅黑樹性質 1.每個節點或是紅的,或是黑的 2.根節點是黑的 3.每個葉結點 nil 都是黑的 4.如果乙個結...

演算法導論例程 紅黑樹

紅黑樹是比較重要的資料結構,作為乙個典型的平衡二叉樹 沒有一條簡單路徑是其他路徑的二倍 它與二叉搜尋樹的區別是它的結點多了乙個屬性 color,color有兩種值,red和black,顏色的選取遵循以下原則 1 每個節點是紅色的,或是黑色的 2 根節點是黑色的 鬆弛紅黑樹 relaxed red b...

演算法導論學習筆記 紅黑樹

紅黑樹的5個性質 1 每個結點要麼是紅的,要麼是黑的。2 根結點是黑的。3 每個葉結點,即空結點 nil 是黑的。4 如果乙個結點是紅的,那麼它的倆個兒子都是黑的。5 對每個結點,從該結點到其子孫結點的所有路徑上包含相同數目的黑結點。public class rbtree 當在某個結點nodex上,...