实现红黑树
来源:互联网 发布:php 压缩图片 编辑:程序博客网 时间:2024/06/06 18:56
红黑树是一个比较常用到数据结构,是一个比AVL树有着更好的搜索能力的树形结构。
红黑树是一种自平衡二叉查找树
典型的用途是实现关联数组。它是复杂的,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。红黑树是一种很有意思的平衡检索树
它的统计性能要好于平衡二叉树(AVL-树),因此,红黑树在很多地方都有应用。在C++ STL中,很多部分(目前包括set, multiset, map, multimap)应用了红黑树的变体(SGI STL中的红黑树有一些变化,这些修改提供了更好的性能,以及对set操作的支持)。
红黑树的每个节点上的属性除了有一个key、3个指针:parent、lchild、rchild以外,还多了一个属性:color。它只能是两种颜色:红或黑。而红黑树除了具有二叉搜索树的所有性质之外,为了方便计算和统计节点的个数,增加了lcount和rcount。具有以下4点性质:
- 根节点是黑色的。
- 空节点是黑色的(红黑树中,根节点的parent以及所有叶节点lchild、rchild都不指向NULL,而是指向一个定义好的空节点)。
- 红色节点的父、左子、右子节点都是黑色。
- 在任何一棵子树中,每一条从根节点向下走到空节点的路径上包含的黑色节点数量都相同。
需要说明的是:红黑树并不是一个红黑交替的树型结构,第一红黑树的性质并没有保证说是不能有两个连续的黑色节点;第二在我们删除的时候是可能存在删除掉了红色节点, 是有可能有连续的两个黑色节点的可能。
#ifndef __RB_TREE_H#define __RB_TREE_H#include <iostream>#include <functional>struct key{ int a;};typedef key KeyType;struct RBTNode { bool color; int lcount; int rcount; KeyType key; RBTNode * leftchild; RBTNode * rightchild; RBTNode * parent;};class RBTree{public: RBTree(RBTNode * p = NULL) :m_root(NULL), m_null(new RBTNode) { m_null->color = BLACK; m_root = m_null; } ~RBTree() { clear(); delete m_null; } bool insert(const KeyType & x) { RBTNode * node = new RBTNode; node->key = x; node->lcount = 0; node->rcount = 0; node->leftchild = m_null; node->rightchild = m_null; //node->parent = m_null; node->color = RED; // new node should set red to keep //each path has the number of black node RBTNode * p = m_root; RBTNode * leaf = m_null; while ( p != m_null){ // find the leaf position leaf = p; if (keycmp (node->key,p->key) < 0){ p->lcount++; p = p->leftchild; } else if (keycmp(node->key,p->key) > 0){ p->rcount++; p = p->rightchild; } else if(keycmp(node->key,p->key) == 0) { return false; } } node->parent = leaf; // connection the tree of the leaf if(leaf == m_null){ m_root = node; } else if( keycmp( node->key,leaf->key) < 0){ leaf->leftchild = node; } else { leaf->rightchild = node; } insbalance(node); return true; } bool del(const KeyType & x) { RBTNode *node = search(x); if(node == NULL) return false; RBTNode * toDel = node; if(node->leftchild != m_null && node->rightchild != m_null){ toDel = Next(node); } // double branch RBTNode *p = toDel; // adujust the number of the child count while (p->parent != m_null){ if(p == p->parent->leftchild){ p->parent->lcount--; } else { p->parent->rcount--; } p = p->parent; } //end while adjust the number of the number // single branch RBTNode *replace = toDel->leftchild != m_null ? toDel->leftchild: toDel->rightchild; replace->parent = toDel->parent; // find the parent node if(replace->parent == m_null){ //m_root m_root = replace; } else if( toDel == toDel->parent->leftchild){ replace->parent->leftchild = replace; } else { replace->parent->rightchild = replace; } if(toDel != node ){ // replace the key value node->key = toDel->key; } if(toDel->color == BLACK){ // this the only case ,need to reblace the tree delbalance(replace); } delete toDel; return true; } RBTNode *atIndex(int i) { RBTNode * result = m_root; if( i > result->lcount + result->rcount){ return NULL; } else { while( i != result ->lcount){ if(i < result->lcount){ result = result->leftchild; } else { i -= result->lcount +1; // 直接掉过左分支 result = result->rightchild; } } } } void toArray(int *arr) { RBTNode * p = Min(); int i = 0; while (p != m_null){ arr[i++] = p->key.a; p = Next(p); } } RBTNode * Max() const { RBTNode * p = m_root; while ( p->rightchild != m_null){ p = p->rightchild; } return p; } RBTNode* Min()const { RBTNode *p = m_root; while (p->leftchild != NULL){ p = p->leftchild; } return p; } int size()const { return m_root != m_null ? m_root->lcount + m_root->rcount + 1 : 0; } RBTNode * search(const KeyType & key) { RBTNode * p = m_root; while( p != m_null && keycmp(key,p->key) != 0){ p = keycmp(key,p->key)<0 ? p->leftchild :p->rightchild; } return p == m_null ? NULL :p; }private: void delbalance(RBTNode *node) { RBTNode *p = node; while ( p != m_root && p->color == BLACK){ if(p == p->parent->leftchild){ // find the node of node's brother RBTNode *sibling = p->parent->rightchild; if(sibling->color == RED){ // sibling->color = BLACK; p->parent->color = RED; leftRotate(p->parent); sibling = p->parent->rightchild; } if(sibling->leftchild->color == BLACK && sibling->rightchild->color == BLACK){ sibling->color = RED; p = p->parent; } else { if(sibling->rightchild->color == BLACK){ sibling->leftchild->color = BLACK; sibling->color = RED; rightRotate(sibling); sibling = sibling->parent; } sibling->color = sibling ->parent->color; sibling->parent->color = BLACK; sibling->rightchild->color = BLACK; leftRotate(sibling->parent); p = m_root; } } else { RBTNode *sibling = p->parent->leftchild; if(sibling->color == RED){ sibling->color = BLACK; p->parent->color = RED; rightRotate(p->parent); sibling = p->parent->leftchild; } if(sibling->leftchild->color == BLACK && sibling->rightchild->color == BLACK){ sibling->color = RED; p = p->parent; } else { if(sibling->leftchild->color == BLACK){ sibling->rightchild->color = BLACK; sibling->color = RED; leftRotate(sibling); sibling = sibling->parent; } sibling->color = sibling->parent->color; sibling->parent->color = BLACK; sibling->leftchild->color = BLACK; rightRotate(sibling->parent); p = m_root; } } } p->color = BLACK; } inline void leftRotate(RBTNode * node ) { RBTNode *newroot = node->rightchild; node->rightchild = newroot->leftchild; node->rcount = newroot->lcount; // newroot left to node's right newroot->leftchild->parent = node; newroot->parent = node->parent; if(newroot->parent == m_null){ m_root = newroot; } else if(node == node->parent->leftchild){ node->parent->leftchild = newroot; } else { node->parent->rightchild = newroot; } newroot->leftchild = node; newroot->lcount += node->lcount+1; node->parent = newroot; } inline void rightRotate(RBTNode *node) { RBTNode * newroot = node->leftchild; node->leftchild = newroot->rightchild; node->lcount = newroot->rcount; node->leftchild->parent = node; newroot->parent = node->parent; if(newroot->parent == m_null){ m_root = newroot; } else if (node == node->parent->leftchild){ node->parent->leftchild = newroot; } else { node->parent->rightchild = newroot; } newroot->rightchild = node; newroot->rcount += node->rcount +1; node->parent = newroot; } void insbalance(RBTNode *node) { RBTNode *z = node; while( z->parent->color == RED){ if(z->parent == z->parent->parent->leftchild){ RBTNode *uncle = z->parent->parent->rightchild; if(uncle->color == RED){ // uncle is red ,to set the color of black: p->parent and uncle , set the p->parent->parent black z->parent->color = BLACK; uncle->color = BLACK; z->parent->parent->color = RED; z = z->parent->parent; // circle to the rebalance : z = z->parent->parent } else { if( z == z->parent->rightchild) { // if z is the right of the parent z = z->parent; leftRotate(z); } z->parent->color = BLACK; z->parent->parent->color = RED; rightRotate(z->parent->parent); } } else { RBTNode *uncle = z->parent->parent->leftchild; if(uncle->color == RED){ z->parent->color = BLACK; uncle->color = BLACK; z->parent->parent->color = RED; z = z->parent->parent; } else { if( z == z->parent->leftchild){ z = z->parent; rightRotate(z); } z->parent->color = BLACK; z->parent->parent->color = RED; leftRotate(z->parent->parent); } } } m_root->color = BLACK; } RBTNode *left(RBTNode * node) { RBTNode * result = node; while (result ->leftchild != m_null){ result = result->leftchild; } return result; } RBTNode *right(RBTNode *node) { RBTNode * result = node; while (result ->rightchild != m_null){ result = result->rightchild; } return result; } RBTNode *Next(RBTNode *node) { if(node == NULL) return NULL; RBTNode * p = node; if(p->rightchild != m_null){ p = left(p->rightchild); } else { p = node->parent; RBTNode * temp = node; while( p != m_null && temp == p->rightchild ){ temp = p; p = p->parent; } } return p; } RBTNode *Prev(RBTNode *node) { if(node == NULL ) return NULL; RBTNode * result = node; if(result ->leftchild != m_null){ result = left(result->rightchild); } else { result = node->parent; RBTNode *temp = node; while (result != m_null && temp == result->leftchild){ temp = result; result = result->parent; } } return result; } inline int keycmp(const KeyType & key1,const KeyType & key2) { return key1.a - key2.a; } void clear() { RBTNode * p = m_root; while(p != m_null){ if(p->leftchild != m_null){ p = p->leftchild; } else if ( p->rightchild != m_null){ p = p->rightchild; } else { RBTNode *temp = p; p = p->parent; if(temp == p->leftchild){ p->leftchild = m_null; } else { p->rightchild = m_null; } delete temp; } } }private: const static bool RED = true; const static bool BLACK = false; RBTNode * m_root; RBTNode * m_null;};#endif
简单的测试:
#include "RBTree.hpp"#include <iostream>using namespace std;int main(){ RBTree tree; KeyType ar[] = {2,45,56,34,54,232,56,567,33,34,56,232,23,44}; int len = sizeof(ar)/sizeof(ar[0]); for(int i = 0; i< len ;i++){ cout<<tree.insert(ar[i]); } cout<<endl; for(int i = 0; i <len;i++){ cout<<tree.del(ar[i]); } return 0;}
详细的解析请看附带的pdf文件
0 0
- 红黑树实现 实现代码
- 红黑树实现
- 红黑树实现
- 红黑树实现
- 红黑树实现
- 红黑树实现
- 红黑树实现
- 实现红黑树
- 红黑树实现
- Josephus排列-红黑树实现-链表实现
- 高效实现红黑树的插入--c实现
- 红黑树: 理论与实现
- 红黑树的实现源码
- 红黑树的实现分析
- 红黑树C实现
- 红黑树算法实现
- 红黑树的C++实现
- 红黑树的实现
- RecyclerViewd的用法
- Python多线程模块
- 如何分析tombstone文件
- 简单理解了下java中的垃圾回收机制
- Android调用摄像头后系统回收activity造成数据丢失
- 实现红黑树
- Java并发编程:线程池的使用
- C++将使用类型转换
- 薄荷Toolbar(ActionBar)的适配方案
- 根据UIview 实现画虚线
- git将当前分支上修改的东西转移到新建分支
- [Leetcode]257. Binary Tree Paths
- 二叉树的java实现
- 计算机信息——注意