红黑树的插入与删除源码

"""
.h头文件
代码基本依据<<算法导论>>的伪代码编写.
代码在mac环境下使用gcc编译器运行良好
"""

1
#ifndef RB_TREE_H__ 2 #define RB_TREE_H__ 3 4 #define NAGETIVE_INFINITY -100000000 5 #define INFINITY 100000000 6 7 typedef enum {RED, BLACK} colorType; 8 9 typedef struct redBlackNode * redBlackTree; 10 typedef struct redBlackNode * position; 11 12 struct redBlackNode 13 { 14 int val; 15 redBlackTree left; 16 redBlackTree right; 17 redBlackTree parent; 18 colorType color; 19 }; 20 21 // init nullNode and return a sign node 22 redBlackTree init(void); 23 // free memory 24 void disposeTree(redBlackTree t); 25 // in-order traversal and output to stdout
26 void inOrderTraversal(redBlackTree t); 27 // insert a node 28 void insertNode(int x, redBlackTree t); 29 // delete a node 30 void deleteNode(int x, redBlackTree t); 31 32 #endif """.c源文件"""

#include <stdio.h> #include <stdlib.h> #include <time.h> #include <assert.h> #include "rb_tree.h" position nullNode = NULL;  // 用于代替NULL节点作为标识 static void test_insert(redBlackTree root, int n); static void test_delete(redBlackTree root, int n, char *input, char *output); inline static void memoryApplyError() { fprintf(stderr, "apply memory fail\n"); exit(1); } // left rotate. // pay attention to handling t->parent relationship when rotating static void singleLeftRotate(redBlackTree x, redBlackTree t) { redBlackTree y, z; y = x->right; x->right = y->left; if (y->left != nullNode) y->left->parent = x; y->parent = x->parent; if (x->parent == t) t->right = y; else if (x == x->parent->left) x->parent->left = y; else x->parent->right = y; x->parent = y; y->left = x; } // right rotate. // pay attention to handling t->parent relationship when rotating static void singleRightRotate(redBlackTree x, redBlackTree t) { redBlackTree y, z; y = x->left; x->left = y->right; if (y->right != nullNode) y->right->parent = x; y->parent = x->parent; if (x->parent == t) t->right = y; else if (x == x->parent->left) x->parent->left = y; else x->parent->right = y; x->parent = y; y->right = x; } // if the uncle node is red and this is the case 1 static redBlackTree redUncle(redBlackTree child, redBlackTree uncle) { uncle->color = child->parent->color = BLACK; child->parent->parent->color = RED; child = child->parent->parent; return child; } // hanle the case that parent node is in the left subtree of the grandparent node static redBlackTree handelInsertLeftCase(redBlackTree child, redBlackTree t) { redBlackTree uncle; uncle = child->parent->parent->right; if (uncle->color == RED) { child = redUncle(child, uncle); } else { // child node is child->left->right; first left rotate; if (child == child->parent->right) { child = child->parent; singleLeftRotate(child, t); } child->parent->color = BLACK; child->parent->parent->color = RED; singleRightRotate(child->parent->parent, t); } return child; } // handle the case that parent node is in the right subtree of the grandparent node static redBlackTree handleInsertRightCase(redBlackTree child, redBlackTree t) { redBlackTree uncle; uncle = child->parent->parent->left; if (uncle->color == RED) { child = redUncle(child, uncle); } else { // child node is grandparent->right->left; first to right rotate if (child == child->parent->left) { child = child->parent; singleRightRotate(child, t); } child->parent->color = BLACK; child->parent->parent->color = RED; singleLeftRotate(child->parent->parent, t); } return child; } static redBlackTree handleDeleteLeftCase(redBlackTree target, redBlackTree t) { redBlackTree brother; brother = target->parent->right; if (brother->color == RED) { brother->color = BLACK; target->parent->color = RED; singleLeftRotate(target->parent, t); brother = target->parent->right; } if (brother->color == BLACK && brother->left->color == BLACK && brother->right->color == BLACK) { brother->color = RED; target = target->parent; } else if (brother->color == BLACK) { if (brother->left->color == RED && brother->right->color == BLACK) { brother->color = RED; brother->left->color = BLACK; singleRightRotate(brother, t); brother = target->parent->right; } brother->color = target->parent->color; target->parent->color = BLACK; brother->right->color = BLACK; singleLeftRotate(target->parent, t);
     t
->left = target; } return target; } static redBlackTree handleDeleteRightCase(redBlackTree target, redBlackTree t) { redBlackTree brother; brother = target->parent->left; if (brother->color == RED) { brother->color = BLACK; target->parent->color = RED; singleRightRotate(target->parent, t); brother = target->parent->left; } if (brother->color == BLACK && brother->left->color == BLACK && brother->right->color == BLACK) { brother->color = RED; target = target->parent; } else { if (brother->right->color == RED && brother->left->color == BLACK) { brother->color = RED; brother->right->color = BLACK; singleLeftRotate(brother, t); brother = target->parent->left; } brother->color = target->parent->color; target->parent->color = BLACK; brother->left->color = BLACK; singleRightRotate(target->parent, t); t->left = target; } return target; } static redBlackTree findMin(redBlackTree target) { while (target->left != nullNode) target = target->left; return target; } static void disposeRealTree(redBlackTree t) { if (t != nullNode) { disposeRealTree(t->left); disposeRealTree(t->right); free(t); } } // repair red-black tree. static void insertFixUp(redBlackTree child, redBlackTree t) { redBlackTree uncle; while (child->parent->color == RED) { // parent node is in the left subtree of the grandparent node if (child->parent == child->parent->parent->left) { child = handelInsertLeftCase(child, t); } else { // parent node is in the right subtree of the grandparent node child = handleInsertRightCase(child, t); } } t->right->color = BLACK; } static redBlackTree rbTransplant(redBlackTree t, redBlackTree origin, redBlackTree target) { if (origin->parent == t) { t->right = target; target->color = BLACK; target->parent = t; } else if (origin == origin->parent->left) { origin->parent->left = target; target->parent = origin->parent; } else { origin->parent->right = target; target->parent = origin->parent; } return target; } static void deleteFixup(redBlackTree t, redBlackTree target) { redBlackTree parent; while ((t->left == target || t->right == target) && target->color == BLACK) { parent = target->parent; // target on the left subtree of the parent node if (target == parent->left) { target = handleDeleteLeftCase(target, t); } else { // target on the right subtree of the parent node target = handleDeleteRightCase(target, t); } } t->left = nullNode; target->color = BLACK; } // create a new tree redBlackTree init(void) { if (nullNode == NULL) { nullNode = malloc(sizeof(struct redBlackNode)); if (nullNode == NULL) memoryApplyError(); nullNode->left = nullNode->right = nullNode->parent = nullNode; nullNode->color = BLACK; } redBlackTree t; t = malloc(sizeof(struct redBlackNode)); if (t == NULL) memoryApplyError(); t->val = NAGETIVE_INFINITY; t->color = BLACK; t->left = t->right = t->parent = nullNode; return t; } void insertNode(int val, redBlackTree t) { redBlackTree child, parent, grandparent, newNode; child = t->right; parent = nullNode; newNode = malloc(sizeof(struct redBlackNode)); if (newNode == NULL) memoryApplyError(); newNode->val = val; newNode->color = RED; newNode->left = newNode->right = nullNode; while (child != nullNode) { parent = child; if (val == child->val) return; else if (val < child->val) child = child->left; else child = child->right; } if (parent == nullNode) { newNode->color = BLACK; t->right = newNode; newNode->parent = t; return; } newNode->parent = parent; if (newNode->val < parent->val) parent->left = newNode; else parent->right = newNode; insertFixUp(newNode, t); } void deleteNode(int val, redBlackTree t) { colorType originalColor; redBlackTree target, replace, minNode; target = t->right; while (val != target->val) { if (val < target->val) target = target->left; else target = target->right; } if (target == nullNode) return ; originalColor = target->color; if (target->left == nullNode) { replace = rbTransplant(t, target, target->right); free(target); } else if (target->right == nullNode) { replace = rbTransplant(t, target, target->left); free(target); } else { minNode = findMin(target->right); originalColor = minNode->color; target->val = minNode->val; replace = rbTransplant(t, minNode, minNode->right); free(minNode); } if (originalColor == BLACK) deleteFixup(t, replace); } static void realInOrderTraversal(redBlackTree t) { assert(t != NULL); if (t != nullNode) { inOrderTraversal(t->left); fprintf(stdout, "val-> %d parent->val = %d color->%s \n", t->val, t->parent->val, t->color == RED ? "red" : "black"); inOrderTraversal(t->right); } } void inOrderTraversal(redBlackTree t) { realInOrderTraversal(t->right); } void disposeTree(redBlackTree t) { disposeRealTree(t->right); free(t); }

 

posted @ 2019-08-13 03:03  少峰  阅读(351)  评论(0编辑  收藏  举报