国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php开源 > php教程 > 红黑树

红黑树

来源:程序员人生   发布时间:2015-07-01 08:50:11 阅读次数:3235次

红黑树满足1下性质:

 *1.节点非红即黑。
 *2.根节点是黑色。
 *3.所有NULL结点称为叶子节点,且认为色彩为黑。
 *4.所有红节点的子节点都为黑色。
 *5.从任1节点到其叶子节点的所有路径上都包括相同数目的黑节点。


因此红黑树插入的所有节点都是红的,然后根据规则进行调剂

再删除的时候,也需要将有两个孩子的节点进行前后的替换,然后删除,最后调剂

/***************************************************************************** * 红黑色: * 或是1颗空树,或是1颗2叉树,满足以下性质 *1.节点非红即黑。 *2.根节点是黑色。 *3.所有NULL结点称为叶子节点,且认为色彩为黑。 *4.所有红节点的子节点都为黑色。 *5.从任1节点到其叶子节点的所有路径上都包括相同数目的黑节点。 * *红黑树具有较好的自平衡性,性能优于BST,但是低于AVL,在linux中用于内存管理 * *因此红黑色在插入节点必定是红节点,由于黑节点会破坏性质5,但是会出现以下问题 *****************************************************************************/ #ifndef REDBLACK_H_ #define REDBLACK_H_ #include <iostream> #define BLACK 1 #define RED 0 using namespace std; /**************每一个节点的信息***********************/ class Node { public: int value;/******节点寄存的值******/ bool color;/***节点色彩****/ Node *leftTree, *rightTree, *parent;/*******左右子树,父节点**********/ Node(void):color(RED),leftTree(NULL),rightTree(NULL),parent(NULL),value(0) {} /**********获得祖父节点************/ Node* grandparent(void) { return parent==NULL?NULL:parent->parent; } /***********获得叔节点***********/ Node* uncle(void) { if (grandparent() == NULL) { return NULL; } if (parent == grandparent()->rightTree) return grandparent()->leftTree; else return grandparent()->rightTree; } /******获得兄弟节点*********/ Node* sibling(void) { return parent->leftTree==this?parent->rightTree:parent->leftTree; } }; /******************红黑色类*********************/ class RedBlackTree { private: void rotate_right(Node *p);/*******右旋********/ void rotate_left(Node *p);/*******左旋********/ void inorder(Node *p);/********先序遍历***********/ string outputColor(bool color);/********输出色彩**********/ Node* getSmallestChild(Node *p);/**********获得最小子树***********/ bool delete_child(Node *p, int data);/*********删除子树************/ void delete_one_child(Node *p);/*********删除1个孩子************/ void delete_case(Node *p);/*********删除情况************/ void insert(Node *p, int data);/********插入*********/ void insert_case(Node *p);/********插入情况***********/ void DeleteTree(Node *p);/********删除树***********/ bool find_data(Node* p,int data);/*********查找节点************/ public: RedBlackTree(void);/********构造接口***********/ ~RedBlackTree();/********烧毁接口***********/ void InOrderTraverse();/********遍历接口***********/ void Insert(int x);/********插入接口***********/ bool Delete(int data);/********删除接口***********/ bool Find(int data);/********查找接口***********/ private: Node *root, *NIL; }; //******************************************************************* // Method: rotate_right // FullName: RedBlackTree::rotate_right // Access: private // Returns: void // Qualifier: 右旋转 // Parameter: Node * p //******************************************************************* //*******************GP********************GP************************ //******************/********************/************************* //****************FA****x****************P****X********************** //***************/******--->***********/*************************** //*************P*****U*****************L**FA************************* //************/*************************Y************************** //***********L***Y***************************U*********************** //******************************************************************* void RedBlackTree::rotate_right(Node *p) { Node *gp = p->grandparent(); Node *fa = p->parent; Node *y = p->rightTree; fa->leftTree = y; if (y != NIL) y->parent = fa; p->rightTree = fa; fa->parent = p; if (root == fa) root = p; p->parent = gp; if (gp != NULL)/******判读父节点与祖父节点的关系,从而修复关系********/ { if (gp->leftTree == fa) gp->leftTree = p; else gp->rightTree = p; } } //******************************************************************* // Method: rotate_left // FullName: RedBlackTree::rotate_left // Access: private // Returns: void // Qualifier: 左旋 // Parameter: Node * p //******************************************************************* //******************************************************************* //*******************GP********************GP************************ //******************/********************/************************* //****************FA****x****************P****X********************** //***************/******--->***********/*************************** //**************X****P*****************FA**R************************* //******************/****************/***************************** //*****************Y***R*************X****Y************************** //******************************************************************* void RedBlackTree::rotate_left(Node *p) { if (p->parent == NULL) { root = p; return; } Node *gp = p->grandparent(); Node *fa = p->parent; Node *y = p->leftTree; fa->rightTree = y; if (y != NIL) y->parent = fa; p->leftTree = fa; fa->parent = p; if (root == fa) root = p; p->parent = gp; if (gp != NULL)/******判读父节点与祖父节点的关系,从而修复关系********/ { if (gp->leftTree == fa) gp->leftTree = p; else gp->rightTree = p; } } //************************************ // Method: inorder // FullName: RedBlackTree::inorder // Access: private // Returns: void // Qualifier: 中序遍历节点 // Parameter: Node * p //************************************ void RedBlackTree::inorder(Node *p) { if (p == NIL) return; if (p->leftTree) inorder(p->leftTree); cout << p->value << " "; if (p->rightTree) inorder(p->rightTree); } //************************************ // Method: outputColor // FullName: RedBlackTree::outputColor // Access: private // Returns: std::string // Qualifier: 输出色彩 // Parameter: bool color //************************************ string RedBlackTree::outputColor(bool color) { return color ? "BLACK" : "RED"; } //************************************ // Method: getSmallestChild // FullName: RedBlackTree::getSmallestChild // Access: private // Returns: Node* // Qualifier: 获得最小孩子 // Parameter: Node * p //************************************ Node* RedBlackTree::getSmallestChild(Node* p) { if (p->leftTree == NIL) return p; return getSmallestChild(p->leftTree); } //************************************ // Method: delete_child // FullName: RedBlackTree::delete_child // Access: private // Returns: bool // Qualifier: 删除孩子 // Parameter: Node * p // Parameter: int data //************************************ bool RedBlackTree::delete_child(Node *p, int data) { if (p->value > data)/*****在左侧*******/ { if (p->leftTree == NIL)/*****没有找到元素*******/ { return false; } return delete_child(p->leftTree, data); } else if (p->value < data)/*****在右侧*******/ { if (p->rightTree == NIL) { return false; } return delete_child(p->rightTree, data); } else if (p->value == data)/*****找到*******/ { if (p->rightTree == NIL) {/******如果节点右子树空了,这样最多只有1个孩子,否则需要替换节点,再进入单节点删除*******/ delete_one_child(p); return true; } Node *smallest = getSmallestChild(p->rightTree);/*找打后继节点,然后交换,后删除*/ swap(p->value, smallest->value); delete_one_child(smallest); return true; } return false; } //************************************ // Method: delete_one_child // FullName: RedBlackTree::delete_one_child // Access: private // Returns: void // Qualifier: 删除最多只有1个孩子的节点 // Parameter: Node * p //************************************ void RedBlackTree::delete_one_child(Node *p) { Node *child = p->leftTree == NIL ? p->rightTree : p->leftTree; if (p->parent == NULL && p->leftTree == NIL && p->rightTree == NIL) {/****只有根节点*******/ p = NULL; root = p; return; } if (p->parent == NULL)/****根节点****/ { delete p; child->parent = NULL;/**重置根节点*/ root = child; root->color = BLACK; return; } if (p->parent->leftTree == p)/**替换掉该节点**/ { p->parent->leftTree = child; } else { p->parent->rightTree = child; } child->parent = p->parent; if (p->color == BLACK) {/*****如果删除的节点是黑节点,需要调剂树,如果是红节点,那末子树也是不冲突的,则直接删除便可********/ if (child->color == RED)/****子树是红节点的话,则直接退换成黑节点,并且性质没有遭到破坏****/ { child->color = BLACK; } else/*******否则需要调剂性质*******/ delete_case(child); } delete p; } //************************************ // Method: delete_case // FullName: RedBlackTree::delete_case // Access: private // Returns: void // Qualifier: 删除情况 // Parameter: Node * p //************************************ void RedBlackTree::delete_case(Node *p) { if (p->parent == NULL)/***为根节点,直接染黑色***/ { p->color = BLACK; return; } if (p->sibling()->color == RED)/****情况1:如果兄弟节点是红色的话,调剂色彩后旋转,最后依照2,3,4处理****/ { p->parent->color = RED; p->sibling()->color = BLACK; if (p == p->parent->leftTree) rotate_left(p->sibling()); else rotate_right(p->sibling()); } if (p->parent->color == BLACK && p->sibling()->color == BLACK && p->sibling()->leftTree->color == BLACK && p->sibling()->rightTree->color == BLACK) {/****情况2.1:父节点黑色,兄弟节点是黑色,而且兄弟有两个黑色的子节点,这样可以染红兄弟,然后调剂父节点****/ p->sibling()->color = RED; delete_case(p->parent); } else if (p->parent->color == RED && p->sibling()->color == BLACK && p->sibling()->leftTree->color == BLACK && p->sibling()->rightTree->color == BLACK) {/****情况2.2:如果兄弟节点是红色的话,而且兄弟有两个黑色的子节点,这样可以染红兄弟,然后调剂父节点****/ p->sibling()->color = RED; p->parent->color = BLACK; } else { if (p->sibling()->color == BLACK) {/****情况3.1:如果兄弟节点是黑色的话,而且兄弟左孩子红色,右孩子黑色,交换兄弟节点和左孩子色彩变成第第4种情况****/ if (p == p->parent->leftTree && p->sibling()->leftTree->color == RED && p->sibling()->rightTree->color == BLACK) { p->sibling()->color = RED; p->sibling()->leftTree->color = BLACK; rotate_right(p->sibling()->leftTree); } else if (p == p->parent->rightTree && p->sibling()->leftTree->color == BLACK && p->sibling()->rightTree->color == RED) {/****情况3.2:如果兄弟节点是黑色的话,而且兄弟左孩子黑色,右孩子红色****/ p->sibling()->color = RED; p->sibling()->rightTree->color = BLACK; rotate_left(p->sibling()->rightTree); } } /****情况4:如果兄弟节点是黑色的话,而且兄弟对面节点孩子为红色****/ p->sibling()->color = p->parent->color; p->parent->color = BLACK; if (p == p->parent->leftTree) {/****情况4.1:节点为左子树,那末兄弟右孩子为红色****/ p->sibling()->rightTree->color = BLACK; rotate_left(p->sibling()); } else {/****情况4.2:节点为右子树,那末兄弟左孩子为红色****/ p->sibling()->leftTree->color = BLACK; rotate_right(p->sibling()); } } } //************************************ // Method: insert // FullName: RedBlackTree::insert // Access: private // Returns: void // Qualifier: 插入数据 // Parameter: Node * p // Parameter: int data //************************************ void RedBlackTree::insert(Node *p, int data) { if (p->value >= data)/**插入数据比data小(含等于)的话,进入左侧,否则进入右侧**/ { if (p->leftTree != NIL) insert(p->leftTree, data); else { Node *tmp = new Node(); tmp->value = data; tmp->leftTree = tmp->rightTree = NIL; tmp->parent = p; p->leftTree = tmp; insert_case(tmp); } } else { if (p->rightTree != NIL) insert(p->rightTree, data); else { Node *tmp = new Node(); tmp->value = data; tmp->leftTree = tmp->rightTree = NIL; tmp->parent = p; p->rightTree = tmp; insert_case(tmp); } } } //************************************ // Method: insert_case // FullName: RedBlackTree::insert_case // Access: private // Returns: void // Qualifier: 插入情况,1共有5种情况 // Parameter: Node * p //************************************ void RedBlackTree::insert_case(Node *p) { if (p->parent == NULL)/****情形1:直接染黑色*****/ { root = p; p->color = BLACK; return; } if (p->parent->color == RED) { if (p->uncle()->color == RED) {/*情形3:父节点和叔节点都是红色,将祖父,父、叔全换色,最后递归处理祖父节点*/ p->parent->color = p->uncle()->color = BLACK; p->grandparent()->color = RED; insert_case(p->grandparent()); } else/*父节点和叔节点都是红色,叔叔节点黑色*/ { if (p->parent->rightTree == p && p->grandparent()->leftTree == p->parent) {/**情形4:p是父节点的右孩子,父节点是祖父节点的左孩子**/ /********这类情况先调剂父节点,使得其和祖父和父亲均在1条线上,注意,这里旋转后p成新的父节点********/ rotate_left(p); rotate_right(p); p->color = BLACK; p->leftTree->color = p->rightTree->color = RED; } else if (p->parent->leftTree == p && p->grandparent()->rightTree == p->parent) {/**情形5:p是父节点的左孩子,父节点是祖父节点的右孩子**/ /********这类情况先调剂父节点,使得其和祖父和父亲均在1条线上,注意,这里旋转后p成新的父节点********/ rotate_right(p); rotate_left(p); p->color = BLACK; p->leftTree->color = p->rightTree->color = RED; } else if (p->parent->leftTree == p && p->grandparent()->leftTree == p->parent) {/**情形5.2:p是父节点的右孩子,父节点是祖父节点的左孩子**/ p->parent->color = BLACK; p->grandparent()->color = RED; rotate_right(p->parent); } else if (p->parent->rightTree == p && p->grandparent()->rightTree == p->parent) {/**情形4.2:p是父节点的右孩子,父节点是祖父节点的左孩子**/ p->parent->color = BLACK; p->grandparent()->color = RED; rotate_left(p->parent); } } } /*******最后斟酌case2:情况,由于父节点是黑色,所以可以直接退出********/ } //************************************ // Method: DeleteTree // FullName: RedBlackTree::DeleteTree // Access: private // Returns: void // Qualifier: 删除树 // Parameter: Node * p //************************************ void RedBlackTree::DeleteTree(Node *p) { if (!p || p == NIL) { return; } DeleteTree(p->leftTree); DeleteTree(p->rightTree); delete p; } //************************************ // Method: find_data // FullName: RedBlackTree::find_data // Access: public // Returns: bool // Qualifier: 查找值 // Parameter: int data //************************************ bool RedBlackTree::find_data(Node* p,int data) { if(p==NULL||p==NIL) return false; if(data>p->value) return find_data(p->rightTree,data); else if(data<p->value) return find_data(p->leftTree,data); return true; } /**************************************接口部份********************************/ //************************************ // Method: RedBlackTree // FullName: RedBlackTree::RedBlackTree // Access: public // Returns: // Qualifier: 初始化 // Parameter: void //************************************ RedBlackTree::RedBlackTree(void) { NIL = new Node(); NIL->color = BLACK; root = NULL; } RedBlackTree::~RedBlackTree(void) { if (root) DeleteTree(root); delete NIL; } //************************************ // Method: inorder // FullName: RedBlackTree::inorder // Access: public // Returns: void // Qualifier: 遍历节点 // Parameter: void //************************************ void RedBlackTree::InOrderTraverse(void) { if (root == NULL) return; inorder(root); cout << endl; } //************************************ // Method: insert // FullName: RedBlackTree::insert // Access: public // Returns: void // Qualifier: 插入值 // Parameter: int x //************************************ void RedBlackTree::Insert(int x) { if (root == NULL) { root = new Node(); root->color = BLACK; root->leftTree = root->rightTree = NIL; root->value = x; } else { insert(root, x); } } //************************************ // Method: delete_value // FullName: RedBlackTree::delete_value // Access: public // Returns: bool // Qualifier: 删除值 // Parameter: int data //************************************ bool RedBlackTree::Delete(int data) { return delete_child(root, data); } //************************************ // Method: Find // FullName: RedBlackTree::Find // Access: public // Returns: bool // Qualifier: 查找值 // Parameter: int data //************************************ bool RedBlackTree::Find(int data) { return find_data(root,data); } #endif /*redblaock.h*/


生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生