java实现红黑树

好久没更新了  今天发个有点技术含量的

 

java实现红黑树代码

下面是代码

 

由于我才疏学浅  和自己对于特别复杂的问题的讲解能力问题   可能不能特别清晰明了的为大家讲解清晰  后面会抽时间整理思路 单独出一篇来讲这个原理

在这之前 为大家推荐 自己在学习过程中找到的比较好的讲解文章

https://www.jianshu.com/p/96e652ccf720

这是链接   

这要求我们对树  平衡树  有一定的了解     不会的可以自己在网上找些教程  这很简单

下面我们上代码

 

此代码为本人原创

不想网上有些地方的直接复制  

对大家应该有不错的参考意义

我想说的是     要理解原理   参透原理    在纸上完全规划好实现的各个方面    然后在进行编码调试

OK  下面看代码

  1 package com.company;
  2 
  3 import java.util.ArrayDeque;
  4 import java.util.LinkedList;
  5 import java.util.Queue;
  6 import java.util.Stack;
  7 
  8 public class RedBlackTree {
  9 
 10     node Head;
 11 
 12 
 13 
 14     public  void NLR(){
 15         // 先序便利
 16         NLr(Head);
 17 
 18     }
 19 
 20     private   void NLr(node now){
 21         // 先序便利
 22         if(now.isNil==false){
 23             System.out.print(now.value +",");
 24             if (now.color==node.RED){
 25                 System.out.println("Red");
 26             }else {
 27                 System.out.println("Black");
 28             }
 29             NLr(now.nextLeft);
 30             NLr(now.nextRight);
 31 
 32 
 33         }else{
 34 
 35         }
 36 
 37     }
 38     public  void LNR(){
 39         // 先序便利
 40         LNr(Head);
 41 
 42     }
 43 
 44     private   void LNr(node now){
 45         // 先序便利
 46         if(now.isNil==false){
 47 
 48             LNr(now.nextLeft);
 49             System.out.print(now.value +"   ");
 50             if (now.color==node.RED){
 51                 System.out.println("Red");
 52             }else {
 53                 System.out.println("Black");
 54             }
 55             LNr(now.nextRight);
 56 
 57 
 58         }else{
 59 
 60         }
 61 
 62     }
 63 
 64 
 65     public  void LOT(){
 66         // 先序便利
 67         LOt(Head);
 68 
 69     }
 70 
 71     private   void LOt(node now){
 72         // 层序遍历
 73         Queue<node> arr = new LinkedList<>();
 74         arr.add(Head);
 75         while (arr.isEmpty()==false ){
 76             node x = arr.poll();
 77             if(x.isNil){
 78 
 79             }else {
 80                 System.out.print(x.value + "  ");
 81                 if (x.color==node.RED){
 82                     System.out.println("Red");
 83                 }else {
 84                     System.out.println("Black");
 85                 }
 86                 if (x.getNextLeft().isNil){
 87 
 88                 }else {
 89                     arr.add(x.getNextLeft());
 90                 }
 91 
 92                 if (x.getNextRight().isNil){
 93 
 94                 }else {
 95                     arr.add(x.getNextRight());
 96                 }
 97             }
 98         }
 99 
100     }
101 
102     public RedBlackTree() {//A constructor
103         Head = new node();
104         Head.isNil = true;
105     }
106 
107     private static node getNIL(){//Get a NIL node
108         node a = new node();
109         a.isNil = true;
110         a.color = 2;
111         return a;
112     }
113 
114 
115     public static void main(String[] args) {
116 //    RedBlackTree c = new RedBlackTree();
117 //    int[] a;
118 //    a= new int[]{50,20,60,10,30,70,40};
119 //    for (int i=0;i<a.length;i++){
120 //      c.addNode(a[i]);
121 //    }
122 //    c.Put();
123 
124 
125         test();
126     }
127 
128 
129     public void chageNode(int Old, int New){// Modification method
130         deletNode(Old);
131         addNode(New);
132 
133     }
134 
135 
136     public int checkNode(int n){//Query method, with this number, returns 0, otherwise returns-1
137         if (getNode(n)!=null){
138             return 0;
139         }else{
140             return -1;
141         }
142     }
143 
144 
145     public void Put() {//Output method
146         PUT(Head);
147         System.out.println();
148     }
149 
150     private void PUT(node head) {//Specific output method
151         if (head == null) {//In the sequence traversal
152             return;
153         }
154         if (head.isNil == false) {
155             PUT(head.nextLeft);
156             System.out.print(head.getValue()+"  ");//A few Spaces in between
157             PUT(head.nextRight);
158         } else {
159             return;
160         }
161     }
162 
163 
164     public int addNode(int n) {//Add methods
165         return addTwo(n);
166         //Failure returns -1
167     }
168 
169     private int addTwo(int n) {//Add a concrete implementation of the method
170         //Find the insert node
171         node to;
172         to = Head;
173         node parent = node.getNIL();//Initialize the parent node to be null
174         while (to.isNil != true) {
175             parent = to;//You need to bind the parent node
176 
177             if (n > to.value) {
178                 to = to.nextRight;
179             } else {
180 
181                 if (n == to.value) {
182                     return -1;//Returns -1 if this number exists
183                 } else {
184                     to = to.nextLeft;
185                 }
186             }
187         }
188         //The parent node has been found
189         //Insert and bind the parent node
190         to.clone(new node(n));
191 
192         to.setParent(parent);//Binding parent node
193         //The node is now found and the insert is complete
194 
195 
196         addFixup(parent, to);//Check balance to maintain balance
197 
198         return -1;
199     }
200 
201 
202     private int addFixup(node parent, node n) {//Added method to maintain balance
203         //Judge each situation
204 
205         if (n.getValue() == Head.getValue()) {//Add nodes as head nodes
206             Head.setColor(2);
207             Head.setParent(null);//Head node condition
208             return 0;
209         }
210 
211         if (parent.getColor() == node.BLACK) {//The parent node is black and ends directly without adjustment
212             return 0;
213         }
214 
215         if (parent.getColor() == node.RED) {
216             //When the father is red, we need the uncle node.
217             //Get the uncle node and grandfather node first
218             node gp = parent.getParent();//Get grandfather node
219             node uncle;//Uncle node
220 
221             if (parent == gp.getNextLeft()) {//Get Uncle Node
222                 uncle = gp.getNextRight();
223             } else {
224                 uncle = gp.getNextLeft();
225             }
226             //The node has been acquired to judge the situation.
227             //Determined that the father is red
228             if (uncle.getColor() == node.RED) {
229                 //Paternal red uncle red condition
230                 //Father Hong, uncle Hong, father and uncle are both black, and their grandfather is black for the new N.
231                 uncle.setBlack();
232                 parent.setBlack();
233                 gp.setRed();
234 
235 
236                 return addFixup(gp.getParent(), gp);//Leveling up
237             } else {
238                 //Paternal red uncle black condition
239                 //Judge the direction
240                 if (gp.getNextLeft() == parent && n == parent.getNextLeft()) {
241                     // PN Same as left
242                     parent.setBlack();
243                     gp.setRed();//Change color first and then rotate to prevent the relationship from getting wrong after rotation.
244                     node i = new node();
245                     i.clone(parent.getNextRight());//Why do you do this temporarily? please refer to the clone method in node.
246                     parent.getNextRight().clone(gp);
247                     parent.getNextRight().setNextLeft(i);
248                     i.setParent(parent.getNextRight());
249                     gp.clone(parent);
250 //                    return addFixup(gp.parent,gp);
251                     return 0;//balance
252                 }
253 
254                 if (gp.getNextRight() == parent && parent.getNextRight() == n ) {
255                     //PN Same as right
256                     parent.setBlack();
257                     gp.setRed();
258                     node i = new node();
259                     i.clone(parent.getNextLeft());//Save the node
260                     parent.getNextLeft().clone(gp);
261                     parent.getNextLeft().setNextRight(i);
262                     i.setParent(parent.getNextLeft());
263                     gp.clone(parent);
264 //                    return  addFixup(gp.parent,gp);
265                     return 0;//Rotation completed and leveled successfully.
266                 }
267 
268                 if (gp.getNextLeft() == parent && parent.getNextRight() == n) {
269                     //P left N right
270                     node ddd = new node();
271                     ddd.clone(n.nextLeft);
272                     parent.setNextRight(ddd);
273                     ddd.setParent(parent);
274                     n.getNextLeft().clone(parent);
275 //                    n.getNextRight().setNextLeft(getNIL());
276 
277                     parent.clone(n);
278                     //Complete the right-hand rotation and now PN is the same as the right.
279                     parent.setBlack();
280                     gp.setRed();
281                     parent = gp.nextLeft;
282                     n = parent.nextLeft;
283                     node i = new node();
284                     i.clone(parent.getNextRight());//Why do you do this temporarily? please refer to the clone method in node.
285                     parent.getNextRight().clone(gp);
286                     parent.getNextRight().setNextLeft(i);
287                     i.setParent(parent.getNextRight());
288                     gp.clone(parent);
289 //                    return addFixup(gp.parent , gp);
290 
291                     return 0;
292                     //Right-hand rotation complete. Leveling complete.
293                 }
294 
295                 if (gp.getNextRight() == parent && parent.getNextLeft() == n) {
296                     //P right N left
297                     node ddd = new node();
298                     ddd.clone(n.nextRight);
299                     parent.setNextLeft(ddd);
300                     ddd.setParent(parent);
301                     n.getNextRight().clone(parent);
302 //                    n.getNextRight().setNextLeft(getNIL());
303 
304                     parent.clone(n);
305                     //Complete the right-hand rotation and now PN is the same as the right.
306                     parent.setBlack();
307                     gp.setRed();
308                     parent = gp.nextRight;
309                     n = parent.nextRight;
310                     node i = new node();
311                     i.clone(parent.getNextLeft());//Save the node
312                     parent.getNextLeft().clone(gp);
313                     parent.getNextLeft().setNextRight(i);
314                     i.setParent(parent.getNextLeft());
315                     gp.clone(parent);
316 //                    return addFixup(gp.parent , gp);
317                     //Complete left-handed rotation
318                     return 0;
319                 }
320                 //The addition situation has been considered.
321             }
322         }
323         return -1;
324     }
325 
326 
327     public node getNode(int n) {//Get node
328         //Find Node
329         if (Head.getValue() == n) {
330             return Head;
331         }
332 
333         node to = Head;
334         while (to.isNil == false && to.getValue() != n) {
335             if (to.getValue() > n) {
336                 to = to.nextLeft;
337             } else {
338                 to = to.nextRight;
339             }
340         }
341         if (to.getValue()==n) {//Whether the search was successful or not
342             return to;
343         } else {
344             return null;
345         }
346     }
347 
348 
349     public int deletNode(int x) {
350         //Delete nod
351         // Get the node first, that is, the node to be deleted
352         node n = getNode(x);
353         return deletNodeTwo(n);//Delete nod
354 
355     }
356 
357 
358     private int deletNodeTwo(node n) {
359         //It is not necessary to delete a node to determine whether it exists or not.
360         if (n == null) {
361             //It doesn't exist.
362             return -1;
363         }
364         if (n.getNextRight()==null){//Prevent null pointers from appearing
365             n.nextRight=getNIL();
366         }
367 
368         if (n.nextLeft==null){
369             n.nextLeft=getNIL();
370         }
371         //It is not empty now and it is a normal node.
372         //Deal with the case without child nodes first
373         if (n.getNextLeft().isNil && n.getNextRight().isNil) {
374             //No child node
375             //To delete as red
376             if (n.getColor() == node.RED) {
377                 n.setValue(-1);
378                 n.isNil = true;//Red no child node is deleted directly.
379                 n.setBlack();
380                 return 0;//There is no need to maintain balance if the deletion is successful.
381             } else {
382                 //Black no child node
383                 //Directly delete the dimension level of the successor NIl node
384                 n.isNil = true;
385                 n.setValue(-1);
386                 //`tain balance with n nodes as unbalanced points
387                 return deletFixup(n);
388             }
389         }
390 
391 
392         //Now there is a child node.
393         if (  (n.getNextRight().isNil && n.getNextLeft().isNil == false) ||
394                 (n.getNextRight().isNil==false && n.getNextLeft().isNil)  ){
395             //Get child nodes
396             node c;
397             if (n.getNextLeft().isNil==false){
398                 c=n.getNextLeft();
399             }else {
400                 c=n.getNextRight();
401             }
402             //Child nodes have been obtained
403             //Judge in the light of each situation
404             if (n.getColor()==node.RED){
405                 n.clone(c);
406                 return 0;
407                 //N is red c must be black direct replacement
408             }else {
409                 //N is black
410                 if (c.getColor()==node.RED){
411                     //If n is black, it is red.
412                     n.clone(c);
413                     n.setBlack();
414                     return 0;
415                     //Replace discoloration
416                 }else {
417                     //N is sunspot and black is black.
418                     n.clone(c);//Replacement leveling
419                     return deletFixup(n);
420                 }
421 
422             }
423         }
424         //The deletion of two child nodes is now handled.
425         if (n.getNextLeft().isNil==false && n.getNextRight().isNil==false){
426             //Find the successor node and then delete the successor node
427             node max=getMax(n);
428             //Get successor node
429             n.setValue(max.value);//Replace
430             //Delete
431             return deletNodeTwo(max);
432             //Balance
433         }
434         return -1;
435     }
436 
437     private int deletFixup(node n){
438         //The parameter is the node to be balanced.
439         if (n==Head){
440             //There is no need to operate when the balance node is the root node.
441             return 0;
442         }
443 
444         //Non-root node
445         //The subsequent operation is to get the relevant nodes.
446         node S,SL,SR,U,GP,Parent;
447         Parent=n.getParent();
448         if (n==Parent.getNextLeft()){
449             S=Parent.getNextRight();
450         }else {
451             S=Parent.getNextLeft();
452         }
453         SL=S.getNextLeft();
454         SR=S.getNextRight();
455         GP=Parent.getParent();
456         if (GP!=null) {
457             if (Parent == GP.getNextLeft()) {
458                 U = GP.getNextRight();
459             } else {
460                 U = GP.getNextLeft();
461             }
462         }
463         //Related nodes have been obtained
464         //Related situation analysis
465 
466         if (S.getColor()==node.BLACK){
467             return SisBlack(Parent,S,SL,SR);
468         }else {
469             //Brother node is red
470             //The brothers are on the left and on the right.
471             if (S ==Parent.getNextLeft()) {
472                 //The brother node is on the left.
473                 S.setBlack();
474                 Parent.setRed();
475                 node i=new node();
476                 i.clone(S.getNextRight());
477                 S.getNextRight().clone(Parent);
478                 S.getNextRight().setNextLeft(i);
479                 i.setParent(S.getNextRight());
480                 Parent.clone(S);
481                 //Complete rotation
482                 Parent=Parent.getNextRight();
483                 S=Parent.getNextLeft();
484                 return SisBlack(Parent,S,S.getNextLeft(),S.getNextRight());
485             }else {
486                 S.setBlack();
487                 Parent.setRed();
488                 node i=new node();
489                 i.clone(S.getNextLeft());
490                 S.getNextLeft().clone(Parent);
491                 S.getNextLeft().setNextRight(i);
492                 i.setParent(S.getNextLeft());
493                 Parent.clone(S);
494                 Parent=Parent.getNextLeft();
495                 S=Parent.getNextRight();
496                 return SisBlack(Parent,S,S.getNextLeft(),S.getNextRight());
497             }
498 
499         }
500 
501     }
502 
503 
504     private int SisBlack(node Parent,node S,node SL,node SR){
505         //The sibling nodes are black
506         if (SL==null){
507             SL=getNIL();
508         }
509 
510         if (SR==null){
511             SR=getNIL();
512         }
513         if (SL.getColor()==node.BLACK && SR.getColor()==node.BLACK){
514             //All sibling nodes are black
515             if (Parent.getColor()==node.BLACK){
516                 //The parent node is black
517                 S.setRed();
518                 return deletFixup(Parent);
519 
520             }else {
521                 //The father of red
522                 Parent.setBlack();
523                 S.setRed();
524                 //The father is black and the brother is red
525                 return 0;
526             }
527         }else {
528             //Not all sibling nodes are black
529             //There are four cases
530 
531             if (S==Parent.getNextLeft() && SL.getColor()==node.RED){
532                 return SisLAndSLisR(Parent,S,SL);
533             }
534 
535             if (S==Parent.getNextRight() && SR.getColor()==node.RED){
536                 //S is the right and the right is red
537                 return SisRAndSRisR(Parent,S,SR);
538             }
539 
540             if (S==Parent.getNextLeft() && SL.getColor()==node.BLACK){
541                 //S is the left subson S is the left subson black and the right subson red
542                 SR.setBlack();
543                 S.setRed();
544                 //First left-handed
545                 node i=new node();
546                 i.clone(SR.getNextLeft());
547                 SR.getNextLeft().clone(S);
548                 SR.getNextLeft().setNextRight(i);
549                 i.setParent(SR.getNextLeft());
550                 S.clone(SR);
551                 SL=S.getNextLeft();
552                 //The new left child
553                 //Left child and left is red
554                 return SisLAndSLisR(Parent,S,SL);
555             }
556 
557             if (S==Parent.getNextRight() && SR.getColor()==node.BLACK){
558                 //S is the right and the right is black and the left is red
559                 if (SL.getNextRight()==null){
560                     SL.nextRight=getNIL();
561                 }
562 
563                 if (SL.getNextLeft()==null){
564                     SL.nextLeft=getNIL();
565                 }
566                 SL.setBlack();
567                 S.setRed();
568                 node i=new node();
569                 i.clone(SL.getNextRight());
570                 SL.getNextRight().clone(S);
571                 SL.getNextRight().setNextLeft(i);
572                 i.setParent(SL.getNextRight());
573                 S.clone(SL);
574                 SR=S.getNextRight();
575                 //The new right is red
576                 return SisRAndSRisR(Parent,S,SR);
577             }
578 
579         }
580         return -1;
581     }
582 
583 
584     private int SisLAndSLisR(node Parent,node S,node SL){
585         S.setColor( Parent.getColor());
586         Parent.setBlack();
587         SL.setBlack();
588         node i=new node();
589         i.clone(S.getNextRight());
590         S.getNextRight().clone(Parent);
591         S.getNextRight().setNextLeft(i);
592         i.setParent(S.getNextRight());
593         Parent.clone(S);
594         //P and S discoloration, the left hand turns black, and the right hand turns black
595         return 0;
596     }
597 
598 
599     private int SisRAndSRisR(node Parent,node S,node SR){
600         //S is the right and the right is red
601         SR.setBlack();
602         S.setColor(Parent.getColor());
603         Parent.setBlack();
604         node i=new node();
605         i.clone(S.getNextLeft());
606         S.getNextLeft().clone(Parent);
607         S.getNextLeft().setNextRight(i);
608         i.setParent(S.getNextLeft());
609         Parent.clone(S);
610         return 0;
611     }
612 
613 
614     //Find the successor node method
615     private static node getMax(node a){
616         //Parameter is the node to be deleted with two child nodes
617         a=a.getNextLeft();
618         while (a.getNextRight().isNil==false){
619             a=a.getNextRight();
620         }
621 
622         return a;
623         //Return successor node
624     }
625 
626     public static void test(){
627         RedBlackTree tree = new RedBlackTree();
628 
629     /*
630     20
631 12 1 9 2 0 11 7 19 4 15 18 5 14 13 10 16 6 3 8 17
632      */
633         int[]data ={12,1,9,2,0,11,7,19,4,15,18,5,14,13,10,16,6,3,8,17};
634 //        String df  = "9   4   1   0   2   3   6   5   7   8   14   12   11   10   13   18   17   19";
635 
636 
637 //        System.out.println(data.length);
638         for(int i = 0;i<data.length;i++){
639             tree.addNode(data[i]);
640 //            tree.LNR();
641 //            System.out.println(data[i]);
642         }
643         tree.LOT();
644 
645     }
646 }
647 
648 
649 class node {
650 
651     static final int RED = 1;
652     static final int BLACK = 2;
653     static node NIL;
654     int value;
655     node nextLeft;//left
656     node nextRight;//right
657     node parent;//parent node
658     boolean isNil;
659     int color;//1 is red//   2 is  black
660 
661     public node() {//The default color is red
662         color = 2;
663         isNil = false;
664     }
665 
666     public node(int n) {
667 
668         value = n;
669         color = 1;
670         this.isNil = false;
671 //        this.toNIL();
672     }
673 
674     public static node getNIL() {
675         node a = new node();
676         a.isNil = true;
677         a.color = 2;
678         return a;
679     }
680 
681     public void setRed() {
682         this.color = RED;
683     }
684 
685     public void setBlack() {
686         this.color = BLACK;
687     }
688 
689     public void clone(node a) {// Cloning methods all clones except the parent node
690         if (a==null){
691             this.isNil=true;
692             return;
693         }
694         if (a.isNil) {
695             this.isNil = true;
696         } else {
697             this.value = a.value;
698             this.color = a.color;
699             if (a.getNextLeft() == null) {
700                 a.nextLeft = getNIL();
701 
702             }else {
703 
704             }
705             this.nextLeft = a.nextLeft;
706             this.nextLeft.setParent(this);
707             if (a.getNextRight() == null) {
708                 a.nextRight = getNIL();
709             }else {
710 
711             }
712             this.nextRight = a.nextRight;
713             this.nextRight.setParent(this);
714 
715 
716             this.isNil = a.isNil;
717         }
718     }
719 
720     public void setNil(boolean nil) {
721         isNil = nil;
722     }
723 
724     public int getValue() {
725         return value;
726     }
727 
728     public void setValue(int value) {
729         this.value = value;
730     }
731 
732     public int getColor() {
733         return color;
734     }
735 
736     public void setColor(int color) {
737         this.color = color;
738     }
739 
740     public node getNextRight() {
741         return nextRight;
742     }
743 
744     public void setNextRight(node nextRight) {
745         this.nextRight = nextRight;
746     }
747 
748     public node getNextLeft() {
749         return nextLeft;
750     }
751 
752     public void setNextLeft(node nextLeft) {
753         this.nextLeft = nextLeft;
754     }
755 
756     public node getParent() {
757         return parent;
758     }
759 
760     public void setParent(node parent) {
761         this.parent = parent;
762     }
763 
764     private void toNIL() {
765         if (this.getNextRight() == null) {
766             this.nextRight = new node();
767             this.nextRight.setBlack();
768             this.getNextRight().isNil = true;
769         }
770 
771         if (this.getNextLeft() == null) {
772             this.nextLeft = new node();
773             this.nextRight.setBlack();
774             this.getNextLeft().isNil = true;
775 
776         }
777     }
778 }

 

 

 

再次声明  原创  原创 原创  引用请注明出处

有瑕疵的地方请大家予以指正

感谢

后面会更新原理讲解  可能会有点慢   感谢

 

 
posted @ 2020-06-19 22:37  Mr小明同学  阅读(355)  评论(0编辑  收藏  举报