算法11---红黑树不带父结点指针的插入实现

Posted taoliu_alex

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法11---红黑树不带父结点指针的插入实现相关的知识,希望对你有一定的参考价值。

算法11---红黑树不带父结点指针的插入实现

  1 #include <iostream>
  2 using namespace std;
  3 #define BLACK 0
  4 #define RED 1
  5 #define Nil -1
  6 #define LEN sizeof(struct Tree)
  7 struct Tree
  8 {
  9    struct Tree*left;
 10    struct Tree*right;
 11    int key;
 12    int color;
 13 };
 14 struct Tree*root=NULL;
 15 struct Tree*nil=NULL;
 16 //非递归版本的二叉查找树查找函数
 17 struct Tree*ITERATIVE_TREE_SEARCH(struct Tree*x,int k,struct Tree*&p1,struct Tree*&p2)
 18 {//
 19     while (x!=nil&&k!=x->key)
 20     {
 21         p1=x;
 22         if (k<x->key)
 23         {
 24             x=x->left;
 25         }
 26         else x=x->right;
 27         if(k!=x->key)//如果没找到了待查找值,那么继续记录其祖父和父结点值。
 28         {
 29             p2=p1;
 30             p1=x;
 31         }
 32     }
 33     return x;
 34 }
 35 void LEFT_ROTATE(struct Tree*T,struct Tree*x)
 36 {//左旋转:分三个步骤①②③来叙述旋转代码的。
 37     struct Tree*p1=nil,*p2=nil;
 38     struct Tree*y=x->right;//设置y结点。
 39     x->right=y->left;//本行代码以及下面的if结构表达的是“y的左孩子成为x的右孩子”。①
 40     ITERATIVE_TREE_SEARCH(root,x->key,p1,p2);
 41     if(p1==nil)//本行代码以及下面的if-else结构表达的过程是“y成为该子树新的根”。②
 42     {
 43        root=y;
 44     }
 45     else if(x==p1->left)
 46     {
 47        p1->left=y;
 48     }
 49     else p1->right=y;
 50     y->left=x;//本行代码以及下面一行都表达了“x成为y的左孩子”。③
 51 }
 52 void RIGHT_ROTATE(struct Tree*T,struct Tree*x)
 53 {//右旋转
 54     struct Tree*p1=nil,*p2=nil;
 55     struct Tree*y=x->left;
 56     x->left=y->right;
 57     ITERATIVE_TREE_SEARCH(root,x->key,p1,p2);
 58     if(p1==nil)
 59     {
 60         root=y;
 61     }
 62     else if(x==p1->right)
 63     {
 64         p1->right=y;
 65     }
 66     else p1->left=y;
 67     y->right=x;
 68 }
 69 void RB_INSERT_INSERT_FIXUP(struct Tree*T,struct Tree*z)
 70 {
 71    struct Tree*p1=nil,*p2=nil; 
 72    ITERATIVE_TREE_SEARCH(root,z->key,p1,p2);//p1=z->parent,p2=z->parent->parent
 73    while (1)
 74    {
 75        ITERATIVE_TREE_SEARCH(root,z->key,p1,p2);//p1是父结点 p2是祖父结点
 76        if (p1->color!=RED)
 77        {
 78            break;
 79        }
 80        if (p1==p2->left)
 81        {
 82            struct Tree*y=p2->right;//叔结点
 83            if (y->color==RED)//情况一:叔结点为红色
 84            {//给p1,y,p2着色以保持性质5。并且解决了z的父结点和z都是红色结点问题
 85                p1->color=BLACK;
 86                y->color=BLACK;
 87                p2->color=RED;
 88                z=p2;//把z的祖父结点当成新结点z进入下一次循环
 89            }
 90            else
 91            {
 92                if (z==p1->right)//情况二:检查z是否是一个右孩子且叔结点为黑色,前提是p1结点不是叶子结点
 93                {//使用一个左旋让情况2转变为情况3
 94                    z=p1;
 95                    LEFT_ROTATE(T,z);//由于进入if语句后可知旋转结点不可能是叶子结点,这样就不用判断z是否是叶子结点了。
 96                 ITERATIVE_TREE_SEARCH(root,z->key,p1,p2);//p1=z->parent,p2=z->parent->parent
 97                }
 98                p1->color=BLACK;//情况三:是z是一个左孩子且叔结点为黑色,改变z的父和祖父结点颜色并做一次右旋,以保持性质5。
 99                p2->color=RED;
100                if(p2!=nil) RIGHT_ROTATE(T,p2);//由于p2可能是叶子结点,所以最好还是用一个if判断
101            }
102        }
103        else//下面else分支类似于上面
104        {
105            struct Tree*y=p2->left;
106            if (y->color==RED)
107            {
108                p1->color=BLACK;
109                y->color=BLACK;
110                p2->color=RED;
111                z=p2;
112            }
113            else
114            {
115                if (z==p1->left)
116                {
117                    z=p1;
118                    RIGHT_ROTATE(T,z);
119                    ITERATIVE_TREE_SEARCH(root,z->key,p1,p2);
120                }
121                p1->color=BLACK;
122                p2->color=RED;
123                if(p2!=nil) LEFT_ROTATE(T,p2);
124            }
125        }
126    }
127    root->color=BLACK;//最后给根结点着为黑色。
128 }
129 void RB_INSERT(struct Tree*T,struct Tree*z)
130 {
131     struct Tree*y=nil;
132     struct Tree*x=root;
133     while (x!=nil)
134     {
135         y=x;
136         if (z->key<x->key)
137         {
138             x=x->left;
139         }
140         else x=x->right;
141     }
142     if (y==nil)
143     {
144         root=z;
145     }
146     else if(z->key<y->key)
147     {
148         y->left=z;
149     }
150     else y->right=z;
151     z->left=nil;
152     z->right=nil;
153     z->color=RED;
154     RB_INSERT_INSERT_FIXUP(T,z);
155 }
156 //中序遍历
157 void InOderTraverse(struct Tree *p)
158 {
159     if (p!=nil)
160     {       
161         InOderTraverse(p->left);
162         cout<<p->key<<" "<<p->color<<" "<<endl;
163         InOderTraverse(p->right);
164     }
165 }
166 void main()
167 {
168     nil=new struct Tree[LEN];
169     nil->key=Nil;nil->color=BLACK;
170     root=nil;
171     int i=0;
172     struct Tree*ROOT=new struct Tree[LEN];
173     cin>>ROOT->key;
174     RB_INSERT(nil,ROOT);
175     root=ROOT;
176     while (i!=12)
177     {
178         struct Tree*z=new struct Tree[LEN];
179         cin>>z->key;
180         RB_INSERT(root,z);
181         i++;
182     }
183     InOderTraverse(root);
184 }

 

以上是关于算法11---红黑树不带父结点指针的插入实现的主要内容,如果未能解决你的问题,请参考以下文章

红黑树(python)-1插入

转载完整简单的红黑树算法

完整简单的红黑树算法

完整简单的红黑树算法

红黑树介绍和结点的插入

红黑树算法的实现与剖析