中学者 发布留言 2008-5-24 19:14 [原创]红黑树源码...写了个公共的平衡树接口....然后写了个红黑树.....功能不多,只能完成字典操作.....顺便试一下飞燕的高亮新版... 不好请多包涵...... PS: 写得好累啊~~~~~ 下面是平衡树接口: /***************************************************************** ** HighlightCodeV3.0 software by yzfy(雨中飞燕) http://yzfy.org ** *****************************************************************/ enum COLOR { RED,BLACK }; template struct node { int key; Ty data; node* leftchild; node* rightchild; node* parent; COLOR color; node(const Ty& v,int k):data(v) { key = k; color = RED; leftchild = rightchild = parent =0; } node(){ color = BLACK; } } ; template class BBST { public: virtual ~BBST() = 0; virtual void Insert(const _value& value,int key)=0; virtual const node<_value>* Delete(int key) =0; virtual const node<_value>* Search(int key) const; bool empty() const ; int size() const ; int height() const ; void InOrder() const ; void PostOrder() const ; void PreOrder() const ; void LevelOrder() const ; protected: node<_value>* root; node<_value>* null; int countNode; protected: virtual void LeftRotate(node<_value>* parent,node<_value>* child) =0; virtual void RightRotate(node<_value>* parent,node<_value>* child) =0; node<_value>* successor(node<_value>* current) const; node<_value>* predecessor(node<_value>* current) const; node<_value>* search(int skey) const; private: int height(const node<_value>* root) const; void inorder(const node<_value>* root) const ; void inorder(node<_value>& root) const ; void postorder(const node<_value>* root) const ; void postorder(node<_value>& root) const ; void preorder(const node<_value>* root) const ; void preorder(node<_value>& root) const ; node<_value>* Minimum(node<_value>* current) const; node<_value>* Maximum(node<_value>* current) const; }; template inline BBST<_Ty>::~BBST() {} // const node<_Ty>* Search(int key) const template inline const node<_Ty>* BBST<_Ty>::Search(int skey) const { return search(skey); } template node<_Ty>* BBST<_Ty>::search(int skey) const { for(node<_Ty>* current=root;current!=null; ) { if(current->key == skey) return current; if(current->key < skey) current = current->rightchild; else current = current->leftchild; } return null; } // Minimum and Maximum template node<_Ty>* BBST<_Ty>::Minimum(node<_Ty>* _node) const { for(node<_Ty>* current=_node;current!=null;) { if( current->leftchild!=null) current = current->leftchild; else return current; } return null; } template node<_Ty>* BBST<_Ty>::Maximum(node<_Ty>* _node) const { for(node<_Ty>* current=_node;current!=null;) { if( current->rightchild!=null) current = current->rightchild; else return current; } return null; } // successor and predecessor template node<_Ty>* BBST<_Ty>::successor(node<_Ty>* current) const { if( current->rightchild!=null) return Minimum(current->rightchild); for(node<_Ty>* __node=current->parent;__node!=null;) { if(__node->leftchild == current) { current = __node; __node = null; } else { current = __node; __node = __node->parent; } } return current; } template node<_Ty>* BBST<_Ty>::predecessor(node<_Ty>* current) const { if( current->leftchild!=null) return Maximum(current->leftchild); for(node<_Ty>* __node=current->parent;__node!=null;) { if(__node->rightchild == current) { current = __node; __node = null; } else { current = __node; __node = __node->parent; } } return current; } // bool empty() const template inline bool BBST<_Ty>::empty() const { return root == null; } // int size() const template inline int BBST<_Ty>::size() const { return countNode; } // int height() const template inline int BBST<_Ty>::height() const { return height(root); } // int height(const node<_Ty>* root) const template int BBST<_Ty>::height(const node<_Ty>* root) const { if( root==null ) return 0; else return height(root->leftchild)>height(root->rightchild)? height(root->leftchild)+1:height(root->rightchild)+1; } // void InOrder() const template void BBST<_Ty>::InOrder() const { // srand((unsigned int)time(0)); inorder(*root); } template void BBST<_Ty>::inorder(const node<_Ty>* root) const { if( root!=null ) { inorder(root->leftchild); std::cout<data<<',' <color<<" "; inorder(root->rightchild); } } template void BBST<_Ty>::inorder( node<_Ty> & root) const { using std::deque; deque*> que; for(node<_Ty>* current=&root; current!=null|| !que.empty(); ) { for(;current!=null ; ) { que.push_front(current); current = current->leftchild; } current = que.front(); que.pop_front(); std::cout<data<<',' <color<<" "; current = current->rightchild; } } // void PostOrder() const template void BBST<_Ty>::PostOrder() const { // srand((unsigned int)time(0)); postorder(*root); } template void BBST<_Ty>::postorder(const node<_Ty>* root) const { if( root!=null ) { postorder(root->leftchild); postorder(root->rightchild); std::cout<data<<',' <color<<" "; } } template void BBST<_Ty>::postorder( node<_Ty>& root) const { using std::deque; deque* > que; for(node<_Ty>* current=&root,*visited=0; current!=null || !que.empty(); ) { for(; current!=null; ) { que.push_front(current); current = current->leftchild; } current = que.front(); que.pop_front(); if(current->rightchild!=null&&visited!=current->rightchild) { que.push_front(current); current = current->rightchild; } else { visited = current; std::cout<data<<',' <color<<" "; current = null; } } } // void PreOrder() const template void BBST<_Ty>::PreOrder() const { // srand((unsigned int) time(0)); preorder(*root); } template void BBST<_Ty>::preorder(const node<_Ty>* root) const { if( root!=null ) { std::cout<data<<',' <color<<" "; preorder(root->leftchild); preorder(root->rightchild); } } template void BBST<_Ty>::preorder( node<_Ty>& root) const { using std::deque; deque*> que; for(node<_Ty>* current=&root;current!=null || !que.empty();) { for( ; current!=null; ) { std::cout<data<<',' <color<<" "; que.push_front(current); current = current->leftchild; } current = que.front(); que.pop_front(); current = current->rightchild; } } // void LevelOrder() const template void BBST<_Ty>::LevelOrder() const { using std::deque; deque*> que; for(node<_Ty>* current=root;current!=null||!que.empty();) { std::cout<data<<',' <color<<" "; if(current->leftchild!=null) que.push_front(current->leftchild); if(current->rightchild!=null) que.push_front(current->rightchild); if(!que.empty()) { current = que.back(); que.pop_back(); } else current = null; } }[/quote]中学者 发布留言 2008-5-24 19:15 下面是红黑树: [quote]/***************************************************************** ** HighlightCodeV3.0 software by yzfy(雨中飞燕) http://yzfy.org ** *****************************************************************/ //------------------ RBT class ------------------------------------ //------------------------------------------------------------------ template class RBT: public BBST<_Ty> { public : RBT(); ~RBT(); void Insert(const _Ty& value,int skey); const node<_Ty>* Delete(int skey); protected : void LeftRotate(node<_Ty>* __parent,node<_Ty>* child); void RightRotate(node<_Ty>* __parent,node<_Ty>* child); private: void free(node<_Ty>* current); void insert_balance(node<_Ty>* current); void delete_balance(node<_Ty>* current); }; // intilization and destroy template inline RBT<_Ty>::RBT() { null = new node<_Ty>; countNode = 0; root = null; } template void RBT<_Ty>::free(node<_Ty>* current) { if( current!=null ) { free(current->leftchild); free(current->rightchild); delete current; } } template RBT<_Ty>::~RBT() { free(root); delete null; } // Insert and Delete template void RBT<_Ty>::Insert(const _Ty& value,int skey) { node<_Ty>* current = root ; if( current!=null ) { for(node<_Ty>* find=current; find!=null;) { if(find->key == skey) return; current = find; if(find->keyfind = find->rightchild; else find = find->leftchild; } node<_Ty>* __node = new node<_Ty>(value,skey); __node->leftchild=__node->rightchild=__node->parent=null; __node->parent = current; if(current->key<__node->key) current->rightchild = __node; else current->leftchild = __node; insert_balance(__node); } else { node<_Ty>* __node = new node<_Ty>(value,skey); __node->leftchild=__node->rightchild=__node->parent=null; __node->parent = root; root = __node; root->color = BLACK; } ++countNode; } template const node<_Ty>* RBT<_Ty>::Delete(int skey) { node<_Ty>* find = search(skey); if(find!=null ) { node<_Ty>* _node,*_nodeParent; if(find->leftchild!=null&&find->rightchild!=null) _nodeParent = successor(find); else _nodeParent = find; if(_nodeParent->leftchild!=null) _node=_nodeParent->leftchild ; else _node=_nodeParent->rightchild; _node->parent = _nodeParent->parent; if(_nodeParent->parent==null) root = _node; else if(_nodeParent == (_nodeParent->parent)->leftchild) (_nodeParent->parent)->leftchild = _node; else (_nodeParent->parent)->rightchild = _node; if(find!=_nodeParent) { find->data = _nodeParent->data; find->key = _nodeParent->key; } --countNode; if(_node->color==BLACK) delete_balance(_node); return _nodeParent; } else return 0; } // LeftRotate and RightRotate template void RBT<_Ty>::LeftRotate(node<_Ty>* __parent,node<_Ty>* child) { __parent->rightchild = child->leftchild; (child->leftchild)->parent = __parent; child->parent = __parent->parent; if(__parent->parent==null) root = child; else if((__parent->parent)->leftchild==__parent) (__parent->parent)->leftchild = child; else (__parent->parent)->rightchild = child; child->leftchild = __parent; __parent->parent = child; } template void RBT<_Ty>::RightRotate(node<_Ty>* __parent,node<_Ty>* child) { __parent->leftchild = child->rightchild; (child->rightchild)->parent = __parent; child->parent = __parent->parent; if(__parent->parent==null) root = child; else if((__parent->parent)->leftchild==__parent) (__parent->parent)->leftchild = child; else (__parent->parent)->rightchild = child; child->rightchild = __parent; __parent->parent = child; } // insert_balance and delete_balance template void RBT<_Ty>::insert_balance(node<_Ty>* current) { for(node<_Ty>* cParent=current->parent; cParent->color==RED; ) { if(cParent==cParent->parent->leftchild) { // case 1 if(cParent->parent->rightchild->color==RED) { cParent->color = BLACK; cParent->parent->rightchild->color = BLACK; cParent->parent->color = RED; current = cParent->parent; } else { // case 2 if(current== cParent->rightchild) LeftRotate(cParent,current); // case 3 cParent->color = BLACK; cParent->parent->color = RED; RightRotate(cParent->parent,cParent); } } else { if(cParent->parent->leftchild->color==RED) { cParent->color = BLACK; cParent->parent->leftchild->color = BLACK; cParent->parent->color = RED; current = cParent->parent; } else { if(current==cParent->leftchild) RightRotate(cParent,current); cParent->color =BLACK; cParent->parent->color = RED; LeftRotate(cParent->parent,cParent); } } } root->color = BLACK; } template void RBT<_Ty>::delete_balance(node<_Ty>* current) { for(node<_Ty>* cParent=current->parent; current!=null&¤t->color==BLACK;) { if(current==cParent->leftchild) { if(cParent->rightchild->color==RED) { LeftRotate(cParent,cParent->rightchild); cParent->color = RED; cParent->rightchild->color = BLACK; } else { if(cParent->rightchild->leftchild->color==BLACK&& cParent->rightchild->rightchild->color==BLACK) { current = cParent; cParent->rightchild->color = RED; } else if(cParent->rightchild->leftchild->color==RED) { RightRotate(cParent->rightchild,cParent->rightchild->leftchild); cParent->rightchild->color = BLACK; cParent->rightchild->rightchild->color = RED; } LeftRotate(cParent,cParent->rightchild); current = root; } } else { if(cParent->leftchild->color==RED) { RightRotate(cParent,cParent->leftchild); cParent->color = RED; cParent->leftchild->color = BLACK; } else { if(cParent->leftchild->rightchild->color==BLACK&& cParent->leftchild->leftchild->color==BLACK) { current = cParent; cParent->leftchild->color = RED; } else if(cParent->leftchild->rightchild->color==RED) { RightRotate(cParent->leftchild,cParent->leftchild->rightchild); cParent->leftchild->color = BLACK; cParent->leftchild->leftchild->color = RED; } LeftRotate(cParent,cParent->leftchild); current = root; } } } current->color = BLACK; } |
中学者 发布留言 2008-5-24 19:16 飞燕的高亮怎么不太亮???[tk02] 中学者 发布留言 2008-5-24 19:21 顺便我有个问题....就是这个平衡树只支持基本类型的关键字.....但是有时候可能会用不是基本类型的关键字.....所以开始我想的是特化类,但是感觉效果很差......最后决定通过hash把非基本类型的关键字转为基本类型来支持多种关键字.....请指教.... PS: 我看的书太少,很多东西不知道.... 雨中飛燕 发布留言 2008-5-24 20:02 牛。。。。红黑树偶还没看懂呢  中学者 发布留言 2008-5-25 13:19 [tk13] [tk13] 我不相信..... StarWing83 发布留言 2008-6-22 20:27 直接模板不就行了?只要对象重载了“<”操作符就可以了 justtest 发布留言 2008-7-27 10:40 红黑树实现#include #include #include #include
typedef struct node { int data; int color; struct node * parent; struct node * left; struct node * right; }node_t, *node_tp;
static node_tp rb_tab_p = NULL;
void free_tab_s(node_tp node) { if(!node) return; free_tab_s(node->left); free_tab_s(node->right); printf("\nfree data=%d", node->data); free(node); }
void free_tab(void) { free_tab_s(rb_tab_p); }
int node_depth(node_tp node, int * blance) { int l,r; if(!node || !node->left || !node->right) return 0; l = node_depth(node->left, blance); r = node_depth(node->right,blance);
if(l - r > 1 || l - r < -1) { printf("\n data=%d depth=%d", node->data, r - l); if(blance && *blance*(*blance) < (r - l)*(r-l)) *blance = r - l; } return (l > r? l: r) + 1; }
int travesal_mid_s(node_tp node) { int l,r,depth = node_depth(node,NULL); if(!node || !node->left || !node->right) return 0; l = travesal_mid_s(node->left ); printf(" %d(%d, %d) ", node->data, node->color, depth); r = travesal_mid_s(node->right); return l + r + 1; }
void travesal_mid(void) { int count, depth, blance = 0; depth = node_depth(rb_tab_p, &blance); printf("\n---------tree is-------------\n"); count = travesal_mid_s(rb_tab_p); printf("\n-----count=%d--depth=%d--blance=%d----------", count, depth, blance); }
node_tp find_node(node_tp node, int data) { if(!node || !node->left || !node->right) return node; else if(node->data > data) return find_node(node->left, data); else if(node->data < data) return find_node(node->right, data); else return node; }
node_tp max_node(node_tp node) { if(!node || !node->right || !node->right->right) return node; return max_node(node->right); }
void init_node(node_tp node, int data, int color) { if(!node) return; node->data = data; node->color = color; node->parent = node->left = node->right = NULL; }
void left_rotate(node_tp node) { node_tp p; int itmp; if(node && node->right) { if(node->right->color == -1 ) node->right->right->color = -1; itmp = node->color; node->color = node->right->color; node->right->color = itmp;
p = node->right; node->right = p->left; p->left = node; p->parent = node->parent; if(!p->parent) rb_tab_p = p; else { if(p->parent->left == node) p->parent->left = p; else p->parent->right = p; } node->parent = p; if(node->right) node->right->parent = node; } }
void right_rotate(node_tp node) { node_tp p; int itmp; if(node && node->left) { if(node->left->color == -1) node->left->left->color = -1; itmp = node->color; node->color = node->left->color; node->left->color = itmp;
p = node->left; node->left = p->right; p->right = node;
p->parent = node->parent; if(!p->parent) rb_tab_p = p; else { if(p->parent->left == node) p->parent->left = p; else p->parent->right = p; } node->parent = p; if(node->left) node->left->parent = node; }
}
void left_right_rotate(node_tp node) { node_tp p; int itmp; if(node && node->left && node->left->right) { itmp = node->color; node->color = node->left->right->color; node->left->right->color = itmp; node->color = node->left->color;
p = node->left->right; node->left->right = p->left; p->left = node->left; node->left = p->right; p->right = node;
p->parent = node->parent; if(!p->parent) rb_tab_p = p; else { if(p->parent->left == node) p->parent->left = p; else p->parent->right = p; } p->left->parent = p; p->right->parent = p; if(p->left->right) p->left->right->parent = p->left; if(p->right->left) p->right->left->parent = p->right;
} }
void right_left_rotate(node_tp node) { node_tp p; int itmp; if(node && node->right && node->right->left) { itmp = node->color; node->color = node->right->left->color; node->right->left->color = itmp; node->color = node->right->color;
p = node->right->left; node->right->left = p->right; p->right = node->right;
node->right = p->left; p->left = node;
p->parent = node->parent; if(!p->parent) rb_tab_p = p; else { if(p->parent->left == node) p->parent->left = p; else p->parent->right = p; } p->left->parent = p; p->right->parent = p; if(p->left->right) p->left->right->parent = p->left; if(p->right->left) p->right->left->parent = p->right;
} }
int insert_rotate_type(node_tp node) { if(node && node->parent->right == node && node->parent->parent->right ==node->parent) return -1; else if(node && node->parent->left == node && node->parent->parent->left ==node->parent) return 1; else if(node && node->parent->right == node && node->parent->parent->left ==node->parent) return -2; else if(node && node->parent->left == node && node->parent->parent->right ==node->parent) return 2; else return 0;
}
void rb_rotate(node_tp node, int type) { switch(type) { case -1: left_rotate(node); break; case 1: right_rotate(node); break; case -2: left_right_rotate(node); break; case 2: right_left_rotate(node); break; default: break; } }
void insert_rb_rotate(node_tp node) { printf("\n11"); rb_rotate(node->parent->parent, insert_rotate_type(node)); }
void insert_color_adjust(node_tp node) { node_tp p; if(!node) return; else if(!node->parent) { node->color = -1; return; }
if(node->color == 1 && node->parent->color == 1) { p = node->parent->parent; if(p->left->color == p->right->color) { p->left->color = p->right->color = -1; p->color = 1; node = p; insert_color_adjust(node); } else insert_rb_rotate(node);
} }
int insert_node_s(node_tp node, int data) { node_tp cur_p, p; cur_p = find_node(node, data); if(cur_p && cur_p->left && cur_p->right) return -1;
if(!cur_p) { cur_p = (node_tp)malloc(sizeof(node_t)); assert(cur_p != NULL); init_node(cur_p, data, -1); rb_tab_p = cur_p; }
p = (node_tp)malloc(sizeof(node_t)); assert(p != NULL); init_node(p, 0,-1); cur_p->left = p; p->parent = cur_p;
p = (node_tp)malloc(sizeof(node_t)); assert(p != NULL); init_node(p, 0,-1); cur_p->right = p; p->parent = cur_p; cur_p->data = data; cur_p->color = 1; insert_color_adjust(cur_p); return 0; }
int insert_node(int data) { return insert_node_s(rb_tab_p, data); }
int del_rotate_type(node_tp black_p) { node_tp parent_p, brother_p; if(black_p && black_p->parent) { parent_p = black_p->parent; if(parent_p->left == black_p) brother_p = parent_p->right; else brother_p = parent_p->left; if(brother_p->color == 1 && brother_p == parent_p->right) return -1; else if(brother_p->color == 1 && brother_p == parent_p->left) return 1; else if(brother_p->color == -1 && brother_p == parent_p->right && brother_p->right->color == 1) return -1; else if(brother_p->color == -1 && brother_p == parent_p->left && brother_p->left->color == 1) return 1; else if(brother_p->color == -1 && brother_p == parent_p->right && brother_p->left->color == 1 && brother_p->right->color == -1) return 2; else if(brother_p->color == -1 && brother_p == parent_p->left && brother_p->left->color == -1 && brother_p->right->color == 1) return -2; } return 0; }
void del_rb_rotate(node_tp node) { rb_rotate(node->parent, del_rotate_type(node)); }
void del_color_adjust(node_tp black_p) { node_tp parent_p, brother_p; if(!black_p) return; else if(black_p == rb_tab_p || black_p->color == 1) { black_p->color = -1; return; } parent_p = black_p->parent; if(parent_p->left == black_p) brother_p = parent_p->right; else brother_p = parent_p->left;
if(brother_p->color == -1 && brother_p->left->color == -1 && brother_p->right->color == -1) { brother_p->color = 1; black_p = black_p->parent; } else if(brother_p->color == 1) { del_rb_rotate(black_p); } else { del_rb_rotate(black_p); black_p = NULL; } del_color_adjust(black_p); }
int del_node_s(node_tp node, int data) { node_tp pre_p, cur_p, black_p = NULL; cur_p = find_node(node, data); if(!cur_p || !cur_p->left || !cur_p->right) return -1; if(!cur_p->left->left) { if(cur_p->color == -1) black_p = cur_p->right;
if(!cur_p->parent) { rb_tab_p = cur_p->right; rb_tab_p->parent = NULL; } else { if(cur_p->parent->left == cur_p) cur_p->parent->left = cur_p->right; else cur_p->parent->right = cur_p->right; cur_p->right->parent = cur_p->parent; } printf("\nfree data=%d", cur_p->data); free(cur_p->left); free(cur_p); if(!rb_tab_p->left || !rb_tab_p->right) { free(rb_tab_p); rb_tab_p = NULL; black_p = NULL; } } else { pre_p = max_node(cur_p->left); if(pre_p->color == -1) black_p = pre_p->left; cur_p->data = pre_p->data;
if(pre_p->parent->left == pre_p) pre_p->parent->left = pre_p->left; else pre_p->parent->right = pre_p->left; pre_p->left->parent = pre_p->parent; printf("\nfree data=%d", pre_p->data); free(pre_p->right); free(pre_p); } del_color_adjust(black_p); return 0;
}
int del_node(int data) { return del_node_s(rb_tab_p, data); }
void input_data(void) {
char str[20]; int data; int ret; int i; for(i = 0; i < 255; i++) insert_node(i); while(1) {
/* printf("\n\nenter data="); scanf("%s", str); if(strncmp(str, "ok", 2) == 0) break; ret = sscanf(str, "%d", &data); if(ret == 1) { travesal_mid(); ret = insert_node(data); if(ret == 0) printf("\ninsert %d successful", data); travesal_mid(); }
*/
travesal_mid(); printf("\n\ndel data="); scanf("%s", str); if(strncmp(str, "ok", 2) == 0) break; ret = sscanf(str, "%d", &data); if(ret == 1) { ret = del_node(data); if(ret == 0) printf("\ndel %d successful", data); travesal_mid(); }
} free_tab();
}
int main(int argc, char **argv) {
input_data();
return 0; }羊口羊 发布留言 2008-7-27 11:59 红黑树?是什么coming 发布留言 2008-7-27 14:12 都好高手~~tyyy 发布留言 2008-7-27 15:58 看不懂啊 谁添加个注释s89475623 发布留言 2008-7-27 17:17 [tk13] 厉害、
页: [1] 特别说明:如网页特效代码中有引用图片文件等,请自己下载到本地调试! |