Red-Black Tree红黑树(插入操作)

来源:互联网 发布:泸州网络春晚 编辑:程序博客网 时间:2024/05/07 04:06

插入操作可能会造成不平衡。

为了使数平衡,AVL树需要rotate操作。那么红黑树怎么弄呢?红黑树需要:

1)recoloring

2) rotate

下面举例说明

假设x是新插入的节点。

1)标准BST树出入,插入后新节点上色为红

2)如果x不为root或者x的父节点不是黑的

   a)如果x的叔节点为红:

       1.变父节点和叔节点的颜色为黑

        2.变爷节点颜色为红

        3.爷节点变为新出入的当前结点

redBlackCase2

   b)如果叔节点是黑色的,那么按照AVL树的四种旋转情况rotate

3)如果x为root,将x的颜色变为黑


下面具体讨论叔节点为黑色时候那四种旋转:

Left Left Case:

redBlackCase3a


Left Right Case

redBlackCase3b


Right Right Case

redBlackCase3c

Right Left Case

redBlackCase3d

插入实例:插入10,20,30,15

Examples


下面是C语言实现代码:

#include <stdio.h>struct node{    int data;// for data part    char color;// for color property    struct node* left;    struct node* right;    struct node* parent;};// leftrotatevoid leftRotate(struct node** root,struct node* x){    // y store the x's right child    struct node* y=x->right;    // update x's righit child    x->right=y->left;    if(x->right!=NULL)    {        x->right->parent=x;    }    // update y's parent pointer    y->parent=x->parent;    // if x's parent is null,make y as root of tree    if(x->parent==NULL)    {        (*root)=y;    }    else if(x==x->parent->left)    {        x->parent->left=y;    }    else    {        x->parent->right=y;    }    y->left=x;    x->parent=y;}// similar to leftrotatevoid rightRotae(struct node** root,struct node* x){    struct node* y=x->left;    x->left=y->right;    if(x->left!=NULL)    {        x->left->parent=x;    }    y->parent=x->parent;    if(x->parent=NULL)    {        (*root)=y;    }    else if(x=x->parent->left)    {        x->parent->left=y;    }    else    {        x->parent->right=y;    }    y->right=x;    x->parent=y;}void insertFixup(struct node** root,struct node* z){    while(z!=*root || z->parent->color=='R')    {        struct node* y;        // find uncle and stroe uncle in y        if(z->parent=z->parent->parent->left)            y=z->parent->parent->right;        else            y=z->parent->parent->left;        // if uncle is red,do following        // 1) change color of parent and uncle as black        // 2) change color of grandparent as red        // 3) move z to grandparent        if(y->color=='R')        {            y->color='B';            z->parent->color='B';            z->parent->parent='R';            z=z->parent->parent;        }        // uncle is black there is four case        else        {            // left left case do following            // 1) swap color parent and grandparent            // 2) right rotete grandparent            if(z=z->parent->left && z->parent=z->parent->parent->left)            {                char t=z->parent->color;                z->parent->color=z->parent->parent->color;                z->parent->parent->color=t;                rightRotae(root,z->parent->parent);            }            // left right case do following            // 1) swap color of current and grandparent            // 2) left rotate parent            // 3) right rotate grandparent            if(z=z->parent->right && z->parent=z->parent->parent->left)            {                char t=z->color;                z->color=z->parent->parent->color;                z->parent->parent->color=t;                leftRotate(root,z->parent);                rightRotae(root,z->parent->parent);            }            // right right case do following            // 1) swap color of parent and grandparent            // 2) left rotate grandparent            if(z=z->parent->right && z->parent=z->parent->parent->right)            {                \char t=z->parent->color;                 z->parent->color=z->parent->parent->color;                 z->parent->parent->color=t;                 leftRotate(root,z->parent->parent);            }            // right left case do following            // 1) swap color of current and grandparent            // 2) right rotate parent            // 3) left rotate grandparent            if(z=z->parent->left && z->parent=z->parent->parent->right)            {                char t=z->color;                z->color=z->parent->parent->color;                z->parent->parent->color=t;                rightRotae(root,z->parent);                leftRotate(root,z->parent->parent);            }        }    }    (*root)->color='B';// keep root always black}void insert(struct node** root,int data){    // allocate memory for new node    struct node* z=(struct node*)malloc(sizeof(struct node));    z->data=data;    z->left=z->right=z->parent=NULL;    // if root is null make z as root    if(root==NULL)    {        z->color='B';        (*root)=z;    }    else    {        struct node* pre=NULL;        struct node* p=(*root);        while(p)        {            pre=p;            if(z->data>p->data)                p=p->right;            else                p=p->left;        }        z->parent=pre;        if(z->data>pre->data)            pre->right=z;        else            pre->left=z;        z->color='R';        insertFixup(root,z);    }}void inorder(struct node* root){    if(root==NULL)        return;    inorder(root->left);    printf("%d ",root->data);    inorder(root->right);}int main(void){    struct node* root=NULL;    insert(&root,5);    insert(&root,3);    insert(&root,7);    insert(&root,2);    insert(&root,4);    insert(&root,6);    insert(&root,8);    insert(&root,11);    inorder(root);    printf("Hello World!\n");    return 0;}


0 0