《演算法導論》好是好,只是看偽**太頭痛了,總想要是有個c語言版的《演算法導論》就好了。
前幾天研究了紅黑樹,把它翻譯成c語言。在vc6.0上編譯測試通過。並且寫了乙個cview類來顯示效果。
標頭檔案 rb_tree.h
#ifndef rb_tree_h
#define rb_tree_h
enum nodecolor ;
typedef int nodedata;
struct rb_tree_node
;struct rb_tree
;void init_rb_tree(rb_tree* t);
void left_rotate(rb_tree* t, rb_tree_node* x);
void right_rotate(rb_tree* t, rb_tree_node* x);
void rb_insert(rb_tree* t, int key, nodedata info = 0);
void rb_insert_(rb_tree* t, rb_tree_node* z);
void rb_insert_fixup(rb_tree* t, rb_tree_node* z);
void rb_delete(rb_tree* t, int key);
void rb_delete_(rb_tree* t, rb_tree_node* z);
void rb_delete_fixup(rb_tree* t, rb_tree_node* x);
int get_tree_height(rb_tree* t, rb_tree_node* x);
#endif
實現檔案:rb_tree.cpp
#include "rb_tree.h"
void init_rb_tree(rb_tree* t)
int get_tree_height(rb_tree* t, rb_tree_node* x)
if(x->right != t->nil)
if(lh > rh)
else
}void left_rotate(rb_tree* t, rb_tree_node* x)
y->parent = x->parent;
if(x->parent == t->nil)
else if(x == x->parent->left)
else
y->left = x;
x->parent = y;
}void right_rotate(rb_tree* t, rb_tree_node* x)
//再把原左子節點替代自己的位置
y->parent = x->parent;
if(x->parent == t->nil)
else if(x == x->parent->right)
else
//最後把自己作為原左子節點的右子節點
y->right = x;
x->parent = y;
}void rb_insert(rb_tree* t, int key, nodedata info)
void rb_insert_(rb_tree* t, rb_tree_node* z)
else if(z->key < x->key)
else
}//插入節點
z->parent = y;
if(y == t->nil)
else if(z->key < y->key)
else
//將新節點的其它域賦值
z->left = t->nil;
z->right = t->nil;
z->color = red;
//修改樹,以滿足紅黑樹的性質
rb_insert_fixup(t, z);
}void rb_insert_fixup(rb_tree* t, rb_tree_node* z)
//如果叔叔節點是黑色,那麼把父節點變成黑色,把祖父節點變成紅色,
//然後右旋轉,使祖父節點成為叔叔節點
else
z->parent->color = black;
z->parent->parent->color = red;
right_rotate(t, z->parent->parent);}}
//下面**是和上面對稱的
else
else
z->parent->color = black;
z->parent->parent->color = red;
left_rotate(t, z->parent->parent);}}
}t->root->color = black;
}rb_tree_node* find_node(rb_tree* t, int key)
else if(key < x->key)
else
}return t->nil;
}void rb_delete(rb_tree* t, int key)
}rb_tree_node* tree_minimum(rb_tree* t, rb_tree_node* x)
return x;
}rb_tree_node* tree_successor(rb_tree* t, rb_tree_node* x)
y = x->parent;
while(y != t->nil && x == y->right)
return y;
}void rb_delete_(rb_tree* t, rb_tree_node* z)
else
//把x設為y的子節點,當然也有可能為nil
if(y->left != t->nil)
else
//從樹中刪除y,但暫時不釋放y所佔記憶體,因為後面還要用到
x->parent = y->parent;
if(y->parent == t->nil)
else
else
}//如果y不等於z,而是z的後驅,則把y的關鍵字和資料拷貝到z
if(y != z)
//如果被刪的y是黑結點,樹的紅黑性質遭到破壞,即黑高度變了,則需要調整
if(y->color == black)
//這時,可以釋放y所佔記憶體了
delete y;
}void rb_delete_fixup(rb_tree* t, rb_tree_node* x)
//如果w的左右子節點都為黑色,把w設為紅色,把x設為x的父節點,
//這時,新x的左右子節點的黑高度就一致了,即x是一顆紅黑樹,但新x的兄節點的
//黑高度仍然大乙個,所以進入下一次循壞,繼續調整
if(w->left->color == black && w->right->color == black)
else
//把w設為父節點的顏色,這樣做是為了在下面的左旋轉後使新舊父節點的顏色不變,
//再把w的父節點和右子節點都設為黑色,然後左旋轉,
//這樣左子節點和右子節點的黑高度就一致了,不用再調整了,所以把x設為root。
w->color = x->parent->color;
x->parent->color = black;
w->right->color = black;
left_rotate(t, x->parent);
x = t->root;}}
//下面**和上面是對稱的
else
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(t, x->parent);
x = t->root;}}
}x->color = black;
}用來顯試效果的ctestrbtreeview類
void ctestrbtreeview::ondraw(cdc* pdc)
#define nodedistance 24
#define radius 20
void ctestrbtreeview::drawrbtree(cdc *pdc, rb_tree* t, rb_tree_node* node, int level, int x, int y)
if(node->color == red)
else
pdc->selectobject(&pen);
crect rect;
rect.left = x - 12;
rect.top = y - 12;
rect.right = x + 12;
rect.bottom = y + 12;
pdc->ellipse(&rect);
cstring str;
str.format("%d", node->key);
if(node->key < 10)
else }
演算法導論紅黑樹C 實現
類封裝了紅黑樹的幾個屬性,水平有限,歡迎批評指正 include header.h enum nodecolor struct rbtreenode rbtreenode const int a class rbtree rbtree rbtree rbtree rbtree void rbtree...
演算法導論紅黑樹的C 實現
按照演算法導論裡的紅黑樹偽 用c 實現了一下,並附帶一些測試 include include using namespace std enum color 顏色標記 templateclass binary tree node 紅黑樹節點 binary tree node parent 父節點 bi...
紅黑樹(演算法導論)
測試 所用的例子為算導第三版p179圖13 4 include using namespace std const bool black 0 黑色 const bool red 1 紅色 struct node 結點結構 class rb tree 初始化nil結點和root node left r...