红黑树
来源:互联网 发布:女生围巾品牌 知乎 编辑:程序博客网 时间:2024/06/18 13:08
/* * 红黑树 * 1 提供基本的操作集: * 得到最大结点 * 得到最小结点 * 得到后继结点 * 得到前驱结点 * 插入结点 * 删除结点 * 2 可以扩展的操作 * 输出一个有序列 * 本例中没有对重复的元素进行控制 * * NIL 这个思想是从《算法导论》中来的 * 有了 NIL 所有的结点都是内结点,便于算法的操作 * * Successor 算法需要明白两种情况,没有右孩子,有右孩子 * InsertNode 算法只插入叶子 * DeleteNode 算法不删除既有右孩子又有左孩子的结点,这种情况需要转化 * */#include <cstdio>#define RED 1#define BLACK 0struct RBNode { int key; int color; RBNode *pParent; RBNode *pLChild; RBNode *pRChild;};class CRBTree {public: CRBTree() { NIL = new RBNode; NIL->color = BLACK; NIL->pParent = NIL; NIL->pLChild = NIL; NIL->pRChild = NIL; root = NIL; } ~CRBTree() { delete NIL; } int GetMaxKey() { RBNode *node = GetMaxNode(root); if (node == NIL) return 0; else return node->key; } int GetMinKey() { RBNode *node = GetMinNode(root); if (node == NIL) return 0; else return node->key; } void InsertKey(int key) { RBNode *node = new RBNode; node->key = key; node->color = RED; node->pParent = NIL; node->pLChild = NIL; node->pRChild = NIL; InsertNode(node); } void DeleteKey(int key) { RBNode *node; while ((node=FindInTree(key)) != NIL) { node = DeleteNode(node); if (node != NIL) delete node; } } bool KeyInTree(int key) { return FindInTree(key) != NIL; }private: RBNode *GetMaxNode(RBNode *node) { RBNode *p = node; while (p->pRChild != NIL) { p = p->pRChild; } return p; } RBNode *GetMinNode(RBNode *node) { RBNode *p = node; while (p->pLChild != NIL) { p = p->pLChild; } return p; } RBNode *FindInTree(int key) { RBNode *p = root; while (p!=NIL && p->key!=key) { if (p->key < key) p = p->pRChild; else p = p->pLChild; } return p; } RBNode *Successor(RBNode *node) { if (node->pRChild != NIL) return GetMinNode(node->pRChild); RBNode *p = node; RBNode *pParent = p->pParent; while (pParent!=NIL && pParent->pRChild==p) { p = pParent; pParent = p->pParent; } return pParent; } RBNode *Predecessor(RBNode *node) { if (node->pLChild != NIL) return GetMaxNode(node->pLChild); RBNode *p = node; RBNode *pParent = p->pParent; while (pParent!=NIL && pParent->pLChild==p) { p = pParent; pParent = p->pParent; } return pParent; } void LeftRotate(RBNode *node) { // x y 都不是 NIL RBNode *x = node; RBNode *y = node->pRChild; y->pParent = x->pParent; if (x->pParent == NIL) root = y; else if (x->pParent->pLChild == x) x->pParent->pLChild = y; else x->pParent->pRChild = y; x->pRChild = y->pLChild; if (x->pRChild != NIL) x->pRChild->pParent = x; y->pLChild = x; x->pParent = y; } void RightRotate(RBNode *node) { // x y 都不是 NIL RBNode *x = node; RBNode *y = node->pLChild; y->pParent = x->pParent; if (x->pParent == NIL) root = y; else if (x->pParent->pLChild == x) x->pParent->pLChild = y; else x->pParent->pRChild = y; x->pLChild = y->pRChild; if (x->pLChild != NIL) x->pLChild->pParent = x; y->pRChild = x; x->pParent = y; } void InsertNode(RBNode *node) { RBNode *p = root; RBNode *pParent = NIL; while (p != NIL) { pParent = p; if (p->key < node->key) p = p->pRChild; else p = p->pLChild; } node->pParent = pParent; if (pParent == NIL) root = node; else if (pParent->key < node->key) pParent->pRChild = node; else pParent->pLChild = node; node->pLChild = NIL; node->pRChild = NIL; node->color = RED; InsertFixup(node); } void InsertFixup(RBNode *node) { RBNode *z = node; while (z->pParent->color==RED) { if (z->pParent==z->pParent->pParent->pLChild) { if (z->pParent->pParent->pRChild->color==RED) { z->pParent->color = BLACK; z->pParent->pParent->pRChild->color= BLACK; z->pParent->pParent->color = RED; z = z->pParent->pParent; } else { if (z->pParent->pRChild == z) { z = z->pParent; LeftRotate(z); } z->pParent->color = BLACK; z->pParent->pParent->color = RED; RightRotate(z->pParent->pParent); } } else { if (z->pParent->pParent->pLChild->color == RED) { z->pParent->color = BLACK; z->pParent->pParent->pLChild->color = BLACK; z->pParent->pParent->color = RED; z = z->pParent->pParent; } else { if (z->pParent->pLChild == z) { z = z->pParent; RightRotate(z); } z->pParent->color = BLACK; z->pParent->pParent->color = RED; LeftRotate(z->pParent->pParent); } } } root->color = BLACK; } RBNode *DeleteNode(RBNode *node) { RBNode *p = NIL; if (node->pLChild==NIL || node->pRChild==NIL) p = node; else p = Successor(node); RBNode *pChild = NIL; if (p->pLChild != NIL) pChild= p->pLChild; else pChild = p->pRChild; pChild->pParent = p->pParent; if (p->pParent == NIL) root = NIL; else if (p->pParent->pLChild == p) p->pParent->pLChild = pChild; else p->pParent->pRChild = pChild; if (p != node) { int tmp = node->key; node->key = p->key; p->key = tmp; } if (p->color == BLACK) DeleteFixup(pChild); if (pChild == NIL) pChild->pParent = NIL; return p; } void DeleteFixup(RBNode *x) { RBNode *w = NIL; while (x != root && x->color==BLACK) { if (x->pParent->pLChild == x) { w = x->pParent->pRChild; if (w->color == RED) { w->color = BLACK; x->pParent->color = RED; LeftRotate(x->pParent); w = x->pParent->pRChild; } if (w->pLChild->color==BLACK && w->pRChild->color==BLACK) { w->color = RED; x = x->pParent; } else { if (w->pRChild->color == BLACK) { w->pLChild->color = BLACK; w->color = RED; RightRotate(w); w = w->pParent; } w->color = x->pParent->color; x->pParent->color = BLACK; w->pRChild->color = BLACK; LeftRotate(x->pParent); x = root; } } else { w = x->pParent->pLChild; if (w->color == RED) { w->color = BLACK; x->pParent->color = RED; RightRotate(x->pParent); w = x->pParent->pLChild; } if (w->pLChild->color==BLACK && w->pRChild->color==BLACK) { w->color = RED; x = x->pParent; } else { if (w->pLChild == BLACK) { w->pRChild->color = BLACK; w->color = RED; LeftRotate(w); w = w->pParent; } w->color = x->pParent->color; x->pParent->color = BLACK; w->pLChild->color = BLACK; RightRotate(x->pParent); x = root; } } } x->color = BLACK; }private: RBNode *NIL; RBNode *root;};int main() { int a[10] = {2, 5, 7, 8, 1, 9 ,10, 3, 4, 6}; CRBTree btree; for (int i=0; i<10; ++i) btree.InsertKey(a[i]); printf("%d %d\n", btree.GetMinKey(), btree.GetMaxKey()); btree.DeleteKey(1); btree.DeleteKey(10); printf("%d %d\n", btree.GetMinKey(), btree.GetMaxKey()); btree.DeleteKey(5); if (btree.KeyInTree(5)) puts("have found 5 in btree"); else puts("can not find 5 in btree"); if (btree.KeyInTree(4)) puts("have found 4 in btree"); else puts("can not find 4 in btree"); return 0;}
0 0
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- git版本控制开发流程小结笔记(一)
- linux SVN服务器创建版本库
- servlet向jsp传数据
- 第8章1节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-运行环境初始化
- c++ primer plus 第六章变成练习 第7题
- 红黑树
- 第8章2节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-解析处理命令行参数
- 10008---AngularJS 控制器
- 单词识别 c++ primer plus 第六章变成练习 第7题
- apk更新、下载、安装(三)---DownloadManager ui方式【有卡顿bug】
- 第8章3节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-启动AndroidDebugBridge
- 深夜喂一口鸡汤
- poj-2342Anniversary party
- poj1459 Power Network