红黑树具体介绍三
依据之前红黑树的原理和《算法导论》上面的伪代码,我用代码将添加和调整的代码实现了一下,如有不正确请大家指正。代码能够结合前两篇文章看。
这次把剩下的删除结加上了,经过測试是能够使用的。
红黑树的具体介绍一
红黑树具体介绍二
/* * ===================================================================================== * * Filename: rbtree->h * * Description: red black tree * * Version: 1->0 * Created: 2014年05月05日 08时48分50秒 * Revision: none * Compiler: gcc * * Author: 我叫程序员XXX * Company: * * ===================================================================================== */ #ifndef __RBTREE__H #define __RBTREE__H #define bool int #define successed 0 #define failed -1 #define BLACK 0 #define RED 1 typedef struct _rbtree_node{ struct _rbtree_node *p; struct _rbtree_node *left; struct _rbtree_node *right; int key; int color; }*p_rbtree_node; struct _rbtree_node node; p_rbtree_node getNode(p_rbtree_node x); bool leftRotate(p_rbtree_node *root, p_rbtree_node x); bool rightRotate(p_rbtree_node *root, p_rbtree_node x); bool rbInert(p_rbtree_node *root, p_rbtree_node z); bool rbInsertFixup(p_rbtree_node *root, p_rbtree_node z); bool rbBuilt(void); bool rbTransplant(p_rbtree_node *root, p_rbtree_node u, p_rbtree_node v); bool rbDeleteFixup(p_rbtree_node *root, p_rbtree_node x); p_rbtree_node Delete(p_rbtree_node z); p_rbtree_node rbDelete(p_rbtree_node *root, p_rbtree_node z); p_rbtree_node treeMinimum(p_rbtree_node z); p_rbtree_node Search(int key); p_rbtree_node priSearch(p_rbtree_node *root, int key); void rbDisplay(p_rbtree_node *root); void Display(void); #endif
rbtree.c
/* * ===================================================================================== * * Filename: rbtree.c * * Description: * * Version: 1.0 * Created: 2014年05月05日 09时01分00秒 * Revision: none * Compiler: gcc * * Author: 我叫程序员XXX * Company: * * ===================================================================================== */ #include "rbtree.h" #include <malloc.h> #include <stdio.h> #include <stdlib.h> #include <string.h> p_rbtree_node nil = &node; p_rbtree_node root; p_rbtree_node getNode(p_rbtree_node x) { x = NULL; x = (p_rbtree_node)malloc(sizeof(struct _rbtree_node)); if (x == NULL) { return NULL; } memset(x, 0, sizeof(struct _rbtree_node)); return x; } bool leftRotate(p_rbtree_node *root, p_rbtree_node x) { p_rbtree_node y = NULL; y = x->right; //set y x->right = y->left; if (y->left != nil) y->left->p = x; y->p = x->p; if (x->p == nil) *root = y; else if (x == x->p->left) x->p->left = y; else x->p->right = y; y->left = x; x->p = y; return successed; } bool rightRotate(p_rbtree_node *root, p_rbtree_node x) { p_rbtree_node y = NULL; y = x->left; x->left = y->right; if (y->right != nil) y->right->p = x; y->p = x->p; if (x->p == nil) *root = y; else if (x == x->p->left) x->p->left = y; else x->p->right = y; y->right = x; x->p = y; return successed; } bool rbInsert(p_rbtree_node *root, p_rbtree_node z) { p_rbtree_node y = nil; p_rbtree_node x = *root; while (x != nil) { y = x; if (z->key < x->key) x = x->left; else x = x->right; } z->p = y; if (y == nil) { *root = z; } else if (z->key < y->key) y->left = z; else y->right = z; z->left = nil; z->right = nil; z->color = RED; rbInsertFixup(root, z); return successed; } bool rbInsertFixup(p_rbtree_node *root, p_rbtree_node z) { while (z->p->color == RED) { p_rbtree_node y = NULL; if (z->p == z->p->p->left) { y = z->p->p->right; if (y->color == RED) { z->p->color = BLACK; y->color = BLACK; z->p->p->color = RED; z = z->p->p; } else if (z == z->p->right) { z = z->p; leftRotate(root, z); } else { z->p->color = BLACK; z->p->p->color = RED; rightRotate(root, z->p->p); } } else { y = z->p->p->left; if (y->color == RED) { z->p->color = BLACK; y->color = BLACK; z->p->p->color = RED; z = z->p->p; } else if (z == z->p->left) { z = z->p; rightRotate(root, z); } else { z->p->color = BLACK; z->p->p->color = RED; leftRotate(root, z->p->p); } } } (*root)->color = BLACK; return successed; } bool rbTransplant(p_rbtree_node *root, p_rbtree_node u, p_rbtree_node v) { if (u->p == nil) { *root = v; } else if (u == u->p->left) { u->p->left = v; } else u->p->right = v; v->p = u->p; return successed; } p_rbtree_node treeMinimum(p_rbtree_node z) { while (z->left != nil) z = z->left; return z; } bool rbDeleteFixup(p_rbtree_node *root, p_rbtree_node x) { p_rbtree_node w = nil; while (x != nil && x->color == BLACK) { if (x == x->p->left) { w = x->p->right; if (w->color == RED) { w->color = BLACK; x->p->color = RED; leftRotate(root, x->p); w = x->p->right; } else if (w->right->color == BLACK && w->left->color == BLACK) { w->color = RED; x = x->p; } else if (w->right->color == BLACK) { w->left->color = BLACK; w->color = RED; rightRotate(root, w); w = x->p->right; } else { w->right->color = BLACK; w->color = x->p->color; w->p->color = BLACK; leftRotate(root, x->p); x = nil; } } else { w = x->p->left; if (w->color == RED) { w->color = BLACK; x->p->color = RED; rightRotate(root, x->p); w = x->p->left; } else if (w->left->color == BLACK && w->right->color == BLACK) { w->color = RED; x = x->p; } else if (w->left->color == BLACK) { w->color = RED; w->right->color = BLACK; leftRotate(root, w); w = x->p->left; } else { w->color = RED; w->left->color = BLACK; w->p->color = BLACK; rightRotate(root, x->p); x = nil; } } } x->color = BLACK; } p_rbtree_node Delete(p_rbtree_node z) { return rbDelete(&root, z); } p_rbtree_node rbDelete(p_rbtree_node *root, p_rbtree_node z) { p_rbtree_node y = nil, x = nil; y = z; int y_original_color = y->color; if (z->left == nil) { x = z->right; rbTransplant(root, z, x); } else if (z->right == nil) { x = z->left; rbTransplant(root, z, x); } else { y = treeMinimum(z->right); y_original_color = y->color; x = y->right; if (y->p == z) { x->p = y; } else { rbTransplant(root, y, x); y->right = z->right; z->right->p = y; } rbTransplant(root, z, y); y->left = z->left; y->left->p = y; y->color = z->color; } if (y_original_color == BLACK) rbDeleteFixup(root, x); return z; } bool rbBuilt() { node.p = NULL; node.left = NULL; node.right = NULL; node.key = -1; node.color = BLACK; root = nil; p_rbtree_node n1 = getNode(n1); n1->key = 1; rbInsert(&root, n1); p_rbtree_node n2 = getNode(n2); n2->key = 2; rbInsert(&root, n2); p_rbtree_node n4 = getNode(n4); n4->key = 4; rbInsert(&root, n4); p_rbtree_node n5 = getNode(n5); n5->key = 5; rbInsert(&root, n5); p_rbtree_node n7 = getNode(n7); n7->key = 7; rbInsert(&root, n7); p_rbtree_node n8 = getNode(n8); n8->key = 8; rbInsert(&root, n8); p_rbtree_node n11 = getNode(n11); n11->key = 11; rbInsert(&root, n11); p_rbtree_node n14 = getNode(n14); n14->key = 14; rbInsert(&root, n14); p_rbtree_node n15 = getNode(n15); n15->key = 15; rbInsert(&root, n15); return successed; } void rbDisplay(p_rbtree_node *root) { if (*root == nil) return; rbDisplay(&((*root)->left)); if ((*root)->color == RED) printf("key=%d, color=RED\n", (*root)->key); else printf("key=%d, color=BLACK\n", (*root)->key); rbDisplay(&((*root)->right)); } void rbMidDisplay(p_rbtree_node *root) { if (*root == nil) return; if ((*root)->color == RED) printf("key=%d, color=RED\n", (*root)->key); else printf("key=%d, color=BLACK\n", (*root)->key); rbMidDisplay(&((*root)->left)); rbMidDisplay(&((*root)->right)); } void Display(void) { rbDisplay(&root); rbMidDisplay(&root); }
test.c 測试文件
* * ===================================================================================== * * Filename: test.c * * Description: * * Version: 1.0 * Created: 2014年05月05日 11时34分19秒 * Revision: none * Compiler: gcc * * Author: 我叫程序员XXX * Company: * * ===================================================================================== */ #include "rbtree.h" #include <stdio.h> int main(void) { rbBuilt(); Display(); int key = 5; p_rbtree_node node = Search(5); p_rbtree_node temp = NULL; temp = Delete(node); printf("*******temp->key = %d**********\n", temp->key); Display(); return 0; }
代码的执行截图例如以下:
代码是通过先序和中序遍历得出的结果。
加入删除之后的执行结果例如以下:
我的编译系统是Linux。编译环境是gcc 版本号 4.8.2 20131212 (Red Hat 4.8.2-7) (GCC) 。后面将删除代码加入上。假设代码中有不论什么不正确的地方。请大家指出。我好及时改动,谢谢大家。