红黑树与二叉树

来源:互联网 发布:win10在端口23连接失败 编辑:程序博客网 时间:2024/06/07 20:49

权且当复习数据结构了。。。

linux内核中有个rbtree改改就能用,stl源码中也有,标准stl中的map和set都只是包装了下rbtree

全部代码:点击打开链接

/************************************************************* * 作者:陈新 * 邮箱:cx2pirate@gmail.com * 时间:2014.6.1 * 环境:gcc * 参考:《算法导论》 * ***********************************************************/#ifndef _HEADER_RB_TREE_#define _HEADER_RB_TREE_typedef int Key;//键值类型typedef int Data;//其他数据typedef enum{BLACK,RED} RB_COLOR;struct rb_node{struct rb_node *parent;struct rb_node *right;struct rb_node *left;RB_COLOR color; Key key;//键值Data data;//数据域};struct rb_root{struct rb_node * rb_node;};extern struct rb_node *RB_NIL;#define rb_parent(r) ((struct rb_node *)((r) ->parent))#define RB_ROOT (struct rb_root){RB_NIL}//插入和删除节点int rb_insert(struct rb_node *,struct rb_root*);struct rb_node * rb_delete(struct rb_node *,struct rb_root*);//只把node从树上卸下来,并没有释放空间struct rb_node * rb_search(Key key,struct rb_root*);/************************************************************** *和二叉树相同,暂时没有实现,rbtree.c中有几个和下面作用相同的函数 *这里时kernel/include/linux/rbtree.h中的声明... * ***********************************************************///查找前趋和后继节点struct rb_node *rb_next(const struct rb_node*);struct rb_node *rb_prev(const struct rb_node*);struct rb_node *rb_first(const struct rb_node*);struct rb_node *rb_last(const struct rb_node*);//后续遍历struct rb_node *rb_first_postorder(const struct rb_root*);struct rb_node *rb_next_postorder(const struct rb_node*);//快速替换某个节点void rb_replace_node(struct rb_node *victim,struct rb_node *new,struct rb_root *root);#endif

#include "rbtree.h"#include <stdio.h>struct rb_node *RB_NIL = &(struct rb_node){0,0,0,BLACK,0,0};//node为树内任意右孩子不为RB_NIL的节点void left_rotate(struct rb_node *node,struct rb_root *root){struct rb_node *rc = node ->right;//rc为node的right childnode ->right = rc ->left;if(rc ->left != RB_NIL){rc ->left ->parent = node;}rc ->parent = node ->parent;if(node ->parent == RB_NIL){//node为root节点root ->rb_node = rc;}else if(node == node ->parent ->left){node ->parent ->left = rc;}else{node ->parent ->right = rc;}rc ->left = node;node ->parent = rc;}//node为树内任意左孩子不为RB_NIL的节点void right_rotate(struct rb_node *node,struct rb_root *root){struct rb_node *lc = node ->left;//lc为node的left childnode ->left = lc ->righif(lc ->right != RB_NIL){//刚开始直接copy过来,少改了个left,debug long long time...lc ->right ->parent = node;}lc ->parent = node ->parent;if(node ->parent == RB_NIL){       //node为root节点root ->rb_node = lc;}else if(node == node ->parent ->left){node ->parent ->left = lc;}else{node ->parent ->right = lc;}lc ->right = node;node ->parent = lc;}//非递归版本二叉树查找//node为根节点,k为键值//返回k节点指针,如果不存在返回RB_NILstruct rb_node *rb_search(Key key,struct rb_root *root){struct rb_node *p = root ->rb_node;while(p != RB_NIL && key != p -> key){p = key < p ->key ? p ->left : p ->right;}return p == RB_NIL ? NULL : p;}//返回以node为根的子树的最小节点struct rb_node *rb_minimum(struct rb_node *node){struct rb_node *p = node;while(p ->left != RB_NIL){p = p ->left;}return p;}//返回以node为根的子树的最大节点struct rb_node *rb_maximum(struct rb_node *node){struct rb_node *p = node;while(p ->right != RB_NIL){p = p ->right;}return p;}//返回node的后继节点struct rb_node *tree_successor(struct rb_node *node){struct rb_node *p = node;if(p ->right != RB_NIL){return rb_minimum(p ->right);}struct rb_node *parent = p ->parent;while(parent != RB_NIL && p == parent ->right){p = parent;parent = parent ->parent;}return parent;}//插入节点后红黑树别破坏的性质2和性质4void rb_insert_fixup(struct rb_node *node,struct rb_root *root){while((rb_parent(node)) ->color == RED){if(rb_parent(node) == rb_parent(rb_parent(node)) ->left){struct rb_node *uc = rb_parent(rb_parent(node)) ->right;if(uc ->color == RED){//case1:叔叔的颜色也为红色uc ->color = BLACK;rb_parent(node) ->color = BLACK;rb_parent(rb_parent(node)) ->color = RED;node = rb_parent(rb_parent(node));}else{if(node == rb_parent(node) ->right){//case2:叔叔为黑色,node为parent的右节点node = rb_parent(node);//通过左旋变为case3left_rotate(node,root);}rb_parent(node) ->color = BLACK;rb_parent(rb_parent(node)) ->color = RED;right_rotate(rb_parent(rb_parent(node)),root);}}else{struct rb_node *uc = rb_parent(rb_parent(node)) ->left;if(uc ->color == RED){//case1:叔叔的颜色也为红色uc ->color = BLACK;rb_parent(node) ->color = BLACK;rb_parent(rb_parent(node)) ->color = RED;node = rb_parent(rb_parent(node));}else{if(node == rb_parent(node) ->left){//case2:叔叔为黑色,node为parent的右节点node = rb_parent(node);//通过左旋变为case3right_rotate(node,root);}rb_parent(node) ->color = BLACK;rb_parent(rb_parent(node)) ->color = RED;left_rotate(rb_parent(rb_parent(node)),root);}}}root ->rb_node ->color = BLACK;}//插入一个节点,与二叉树区别不大,最后需要调用rb_insert_fixup修复红黑性质int rb_insert(struct rb_node *node,struct rb_root *root){struct rb_node *parent = RB_NIL;//node在树中的父亲struct rb_node *p = root ->rb_node;while(p != RB_NIL){parent = p;if(node ->key < p ->key){p = p ->left;}else if(node ->key > p ->key){p = p ->right;}else{return 0;}}node ->parent = parent;if(parent == RB_NIL){root ->rb_node = node;}else if(node ->key < parent ->key){parent ->left = node;}else{parent ->right = node;}node ->left = RB_NIL;node ->right = RB_NIL;node ->color = RED;rb_insert_fixup(node,root);return 0;}void rb_delete_fixup(struct rb_node *node,struct rb_root *root){struct rb_node *sibiling;while(node != root ->rb_node && node ->color == BLACK){//node has double black attrubuteif(node == rb_parent(node) ->left){//!note:node could be RB_NILsibiling = rb_parent(node) ->right;//!note:double black node certainly has a brotherif(sibiling ->color == RED){//case 1:brother's color is redsibiling ->color = BLACK;//and sibiling has two black childrb_parent(node) ->color = RED;//aparenter this,case 1 will be turned to left_rotate(rb_parent(node),root);//case2,case 3 or case 4.sibiling = rb_parent(node) ->right;}if(sibiling ->left ->color == BLACK && sibiling ->right ->color == BLACK){sibiling ->color = RED;node = rb_parent(node);//case 2:双重黑色上移到父亲,循环迭代.}else{ if(sibiling ->right ->color == BLACK){//case 3:变为case 4sibiling ->left ->color = BLACK;sibiling ->color = RED;right_rotate(sibiling,root);sibiling = rb_parent(node) ->right;}sibiling ->color = rb_parent(node) ->color;//case 4:rb_parent(node) ->color = BLACK;sibiling ->right ->color = BLACK;left_rotate(rb_parent(node),root);node = root ->rb_node;//case 4经过此步就结束了}}else{sibiling = rb_parent(node) ->left;//double black node certainly has a brotherif(sibiling ->color == RED){//case 1:brother's color is redsibiling ->color = BLACK;//and sibiling has two black childrb_parent(node) ->color = RED;//aparenter this,case 1 will be turned to right_rotate(rb_parent(node),root);//case2,case 3 or case 4.sibiling = rb_parent(node) ->left;}if(sibiling ->left ->color == BLACK && sibiling ->right ->color == BLACK){sibiling ->color = RED;node = rb_parent(node);//case 2:double black move up.}else{if(sibiling ->left ->color == BLACK){//case 3:sibiling ->right ->color = BLACK;sibiling ->color = RED;left_rotate(sibiling,root);sibiling = rb_parent(node) ->left;}sibiling ->color = rb_parent(node) ->color;//case 4:rb_parent(node) ->color = BLACK;sibiling ->left ->color = BLACK;right_rotate(rb_parent(node),root);node = root ->rb_node;//case 4经过此步就结束了}}}node ->color = BLACK;}struct rb_node * rb_delete(struct rb_node *node,struct rb_root *root){struct rb_node *p,*ps;//p为待删除节点,ps为p的子节点if(node ->left == RB_NIL || node -> right == RB_NIL){p = node;}else{p = tree_successor(node);}ps = p ->left != RB_NIL ? p ->left : p ->right;ps ->parent = p ->parent;//different from binary_tree,ps could be NILif(p ->parent == RB_NIL){root ->rb_node = ps;}else if(p == rb_parent(p) ->left){rb_parent(p) ->left = ps;}else{rb_parent(p) ->right = ps;}if(p != node){//复制key域,如果还有其它数据需要一同复制{node ->key = p ->key;node ->data = p ->data;}if(p ->color == BLACK){//black node is deletedrb_delete_fixup(ps,root);}return p;}

0 0
原创粉丝点击