java实现红黑树


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

java实现红黑树代码

下面是代码

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

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

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

这是链接   

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

下面我们上代码

此代码为本人原创

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

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

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

OK  下面看代码

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

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

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

感谢

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