Left-Rotate(T, x){ y = x.right //定義y是x的右孩子 x.right = y.left //y的左孩子成爲x的右孩子 if(y.left != T.nil) y.left.p = x //若是y左孩子不是nil y.p = x.p //x結點成爲y的父結點 if(x.p == T.nil) T.root = y //若是x是根結點,y成爲根結點 else if(x == x.p.left) x.p.left = y //肯定y新成爲左孩子仍是右孩子 else x.p.right = y y.left = x //x成爲y的左孩子 x.p = y }
Right-Rotate(T,x){ y = x.left //定義y是x的左孩子 x.left = y.right //y的右孩子成爲x的左孩子 if(y.right != T.nil) y.left.p = x y.p = x.p //x結點成爲y的父結點 if(x.p == T.nil) T.root = y //若是x是根結點,y成爲根結點 else if(x == x.p.left) x.p.left = y //肯定y新成爲左孩子仍是右孩子 else x.p.right = y y.right = x //x成爲y的左孩子 x.p = y }
RB-Insert(T,z){ y = nil x = T.root while(x != T.nil){ y = x //找出z的父結點y的位置 if(z.key < x.key) x = x.left else x = x.right } z.p = y if(y == nil[T]) T.root = z//判斷z要插入的位置 else if(z.key < y.key) y.left = z else y.right = z z.left = T.nil z.right = T.nil z.color = RED RB-Insert_Fixup(T,z) }
RB-Insert-Fixup(T,z){ while(z.p.color == RED){//全部修復狀況父結點都是紅色 if(z.p == z.p.p.left){ y = z.p.p.right if(y.color == RED){//狀況1:叔叔結點是紅色 z.p.color = BLACK//父變黑 y.color = BLACK//叔變黑 z.p.p.color = RED//祖變紅 z = z.p.p//將祖父當作新增結點z,z上移兩個指針且爲紅色 } else {//叔叔結點是黑色 if(z == z.p.right){//狀況2:當前結點是父結點的右子 z = z.p//父與子角色互換 Left-Rotate(T,z)//左旋 }//狀況3:當前結點是父結點的左子 z.p.color = BLACK//父變黑 z.p.p.color = RED//祖變紅 Right-Rotate(T,z.p.p)//祖右旋 } } else{ y = z.p.p.left if(y && y.color == RED){ z.p.color = BLACK y.color = BLACK z.p.p.color = RED z = z.p.p } else{ if(z == z.p.left){ z = z.p Right-Rotate(T,z) } z.p.color = BLACK z.p.p.color = RED Left-Rotate(T,z.p.p) } } } T.root.color = BLACK//根確定是黑的 return root }
(特此說明:當前代指當前結點,父代指父結點,叔代指父的兄弟結點,祖代指祖父結點,數字1,2,3,4,5代指上述對應性質)數組
RB-Transplant(T,x,y){ //找到安放y的位置 //用y頂替x的位置 if(x.p == T.nil) T.root = y else if(x == x.p.left) x.p.left = y else x.p.right = y y.p = x.p } RB-Delete(T,z){ y = z //記錄要刪除結點的原信息 y-origial-color = y.color if(z.left == T.nil){//被刪除結點只有一個孩子的狀況 x = z.right RB-Transplant(T,z,z.right) } else if(z.right == T.nil){//被刪除結點只有一個孩子的狀況 x = z.left RB-Transplant(T,z,z.left) } else{//y是z的後繼結點 y = Tree-Minium(z.right) //這裏也能夠是Tree-Maxmun(z.left),不過下面要修改 y-origial-color = y.color x = y.right if(y.p == z) x.p = y//若是y是z的直系孩子,z右邊只有一個孩子的狀況,綁定x和y else{ RB-Transplant(T,y,y.right)//用y.right頂替y的位置 y.right = z.right//y接管z的右孩子 y.right.p = y } RB-Transplant(T,z,y)//用y頂替z的位置 y.left = z.left//y接管z的左孩子 y.left.p = y y.color = z.color//y接管z的顏色 }//若是y原來是黑色的,進行修復 if(y-origial-color == BLACK) RB-Delete-Fixup(T,x) }
RB-Delete-Fixup(T,z){ while(z != T.root && z.color == BLACK){//z一直往上移 if(z == z.p.left){ w = z.p.right//w是z的兄弟結點 if(w.color == RED){//狀況1:w是紅色 w.color = BLACK //兄變黑 z.p.color = RED //父變紅 Left-Rotate(T,z.p) //父左旋 w = z.p.right //重置兄 } if(w.left.color == BLACK && w.right.color == BLACK){//狀況2:兄和其兩孩子都是黑 w.color = RED //兄變紅 z = z.p //父爲新當前 } else{ if(w.right.color == BLACK){ //狀況3:兄的孩左紅右黑 w.left.color = BLACK //兄左孩變黑 w.color = RED //兄變紅 Right-Rotate(T,w) //兄右旋 w = z.p.right //重置兄 } //狀況4:兄的孩左右皆紅 w.color = z.p.color //兄顏色變爲父 z.p.color = BLACK //父變黑 w.right.color = BLACK //兄右孩變黑 Left-Rotate(T,z.p) //父左旋 z = T.root //當前爲根 } } else{ w = z.p.left//w是z的兄弟結點 if(w.color == RED){//狀況1:w是紅色 w.color = BLACK //兄變黑 z.p.color = RED //父變紅 Right-Rotate(T,z.p) //父右旋 w = z.p.left //重置兄 } if(w.right.color == BLACK && w.left.color == BLACK){//狀況2:兄和其兩孩子都是黑 w.color = RED //兄變紅 z = z.p //父爲新當前 } else{ if(w.left.color == BLACK){ //狀況3:兄的孩右紅左黑 w.right.color = BLACK //兄右孩變黑 w.color = RED //兄變紅 Left-Rotate(T,w) //兄左旋 w = z.p.left //重置兄 } //狀況4:兄的孩左右皆紅 w.color = z.p.color //兄顏色變爲父 z.p.color = BLACK //父變黑 w.left.color = BLACK //兄左孩變黑 Right-Rotate(T,z.p) //父右旋 z = T.root //當前爲根 } } } z.color = BLACK }
解法:將兄染成父,父染黑,兄的右子染黑,父左旋,設當前爲根節點ssh
通過根和兄右子的路徑違背5,因此可在知足上一條件時,將兄右子染黑url