用Java實現紅黑樹的完整程式碼
阿新 • • 發佈:2019-01-04
//對某個節點進行左旋
public void leftRonate(RBNode<T> x) {
RBNode<T> y = x.rightChild;
if(y.leftChild!=null) {
y.leftChild.parent = x;
}
x.rightChild = y.leftChild;
y.leftChild = x;
y.parent = x.parent;
if(x.parent!=null) {
if(x.parent.leftChild == x) {
x.parent.leftChild = y;
}else {
x.parent.rightChild = y;
}
}else {
this.mroot = y;
}
x.parent = y;
}
//對某個節點進行右旋
public void rightRonate(RBNode<T> x) {
RBNode<T> y = x.leftChild;
if(y.rightChild!=null) {
y.rightChild.parent = x;
}
y.parent = x.parent;
x.leftChild = y.rightChild;
y.rightChild = x;
if(x.parent!=null) {
if(x.parent.leftChild == x) {
x.parent.leftChild = y;
}else {
x.parent.rightChild = y;
}
}else {
this.mroot = y;
}
x.parent = y;
}
//紅黑樹新增修復
public void insertFixUp(RBNode<T> node) {
RBNode<T> parent,gparent;
while(((parent = parentOf(node))!=null)&&isRed(parent)) {
gparent = parentOf(parent);
if(gparent.leftChild == parent) {
RBNode<T> uncle = gparent.rightChild;
if(isRed(uncle)){
setBlack(parent);
setBlack(uncle);
setRed(gparent);
node = gparent;
continue;
}else {
if(parent.rightChild == node) {
leftRonate(parent);
RBNode<T> temp = node;
node = parent;
parent = temp;
}
setBlack(parent);
setRed(gparent);
rightRonate(gparent);
}
}else {
RBNode<T> uncle = gparent.leftChild;
if(isRed(uncle)) {
setBlack(parent);
setBlack(uncle);
setRed(gparent);
node = gparent;
continue;
}else {
if(parent.leftChild == node) {
rightRonate(parent);
RBNode<T> temp = node;
node = parent;
parent = temp;
}
setBlack(parent);
setRed(gparent);
leftRonate(gparent);
}
}
}
if(mroot == node) {
setBlack(node);
}
}
//紅黑樹刪除修復
public void deleteFixUp(RBNode<T> node,RBNode<T> parent) {
RBNode<T> other;
while(isBlack(node)&&node!=this.mroot) {
if(parent.leftChild == node) {
other = parent.rightChild;
if(isRed(other)) {
setRed(parent);
setBlack(other);
leftRonate(parent);
continue;
}else {
if(isBlack(other.leftChild)&&isBlack(other.rightChild)) {
setRed(other);
node = parent;
parent = parentOf(node);
}else if(isRed(other.leftChild)&&isBlack(other.rightChild)) {
setRed(other);
setBlack(other.leftChild);
rightRonate(other);
}else if(isRed(other.rightChild)) {
setColor(other,colorOf(parent));
setBlack(parent);
setBlack(other.rightChild);
leftRonate(parent);
break;
}
}
}else {
other = parent.leftChild;
if(isRed(other)) {
setBlack(other);
setRed(parent);
rightRonate(parent);
continue;
}else {
if(isBlack(other.leftChild)&&isBlack(other.rightChild)) {
setRed(other);
node = parent;
parent = parentOf(node);
}else if(isRed(other.rightChild)&&isBlack(other.leftChild)) {
setRed(parent);
setBlack(other.rightChild);
leftRonate(other);
}else if(isRed(other.leftChild)) {
setColor(other, colorOf(parent));
setBlack(parent);
setBlack(other.leftChild);
rightRonate(parent);
break;
}
}
}
}
setBlack(node);
}
//紅黑樹新增操作
public void insert(RBNode<T> node) {
int com;
RBNode<T> x = this.mroot;
RBNode<T> y = null;
while(x!=null) {
y = x;
com = node.key.compareTo(x.key);
if(com<0) {
x=x.leftChild;
}else{
x=x.rightChild;
}
}
node.parent = y;
if(y!=null) {
com = node.key.compareTo(y.key);
if(com<0) {
y.leftChild = node;
}else {
y.rightChild = node;
}
}else {
this.mroot = node;
}
setRed(node);
insertFixUp(node);
}
public void insert(T key) {
RBNode<T> node = new RBNode<T>(BLACK,key,null,null,null);
if(node!=null) {
insert(node);
}
}
//紅黑樹刪除操作
public void delete(RBNode<T> node) {
RBNode<T> child,parent,replace;
boolean color = true;
if(node.leftChild!=null&&node.rightChild!=null) {
replace = successor(node);
parent = parentOf(replace);
child = replace.rightChild;
color = colorOf(replace);
if(node == parentOf(replace)) {
parent = replace;
}else {
if(child!=null) {
setParent(child,parentOf(replace));
}
replace.parent.leftChild = child;
replace.rightChild = node.rightChild;
setParent(node.rightChild,replace);
}
setParent(replace, parentOf(node));
replace.leftChild = node.leftChild;
setParent(node.leftChild,replace);
setColor(replace,colorOf(node));
if(parentOf(node)!=null) {
if(node.parent.leftChild==node) {
node.parent.leftChild = replace;
}else {
node.parent.rightChild = replace;
}
}else {
this.mroot = replace;
}
if(color==BLACK){
deleteFixUp(child, parent);
}
}else {
if(node.leftChild!=null) {
replace = node.leftChild;
}else {
replace = node.rightChild;
}
parent = parentOf(node);
if(parent!=null) {
if(parent.leftChild==node) {
parent.leftChild = replace;
}else {
parent.rightChild = replace;
}
}else {
this.mroot = replace;
}
setParent(replace, parent);
color = colorOf(node);
child = replace;
if(color==BLACK) {
deleteFixUp(child, parent);
}
}
}
public void delete(T key) {
RBNode<T> node;
if((node=search(key,this.mroot))!=null) {
delete(node);
}
}
//前序遍歷
public void preOrder(RBNode<T> node) {
if(node!=null) {
System.out.print(node.key+" ");
preOrder(node.leftChild);
preOrder(node.rightChild);
}
}
public void preOrder() {
preOrder(this.mroot);
}
//中序遍歷
public void inOrder(RBNode<T> node) {
if(node!=null) {
inOrder(node.leftChild);
System.out.print(node.key+" ");
inOrder(node.rightChild);
}
}
public void inOrder() {
inOrder(this.mroot);
}
//後序遍歷
public void postOrder(RBNode<T> node) {
if(node!=null) {
postOrder(node.leftChild);
postOrder(node.rightChild);
System.out.print(node.key+" ");
}
}
public void postOrder() {
postOrder(this.mroot);
}
//列印紅黑樹
public void print(RBNode<T> node,int direction) {
if(node!=null) {
if(direction == 0) {
System.out.printf("%2d(%s) is root\n",node.key,node.color==false?"R":"B");
}else {
System.out.printf("%2d(%s) is %s child 父節點 %2d\n",node.key,node.color==false?"R":"B",direction==-1?"left":"right",node.parent.key);
}
print(node.leftChild,-1);
print(node.rightChild,1);
}
}
public void print() {
print(this.mroot,0);
}
public static void main(String[] args) {
DRBTree<Integer> tree = new DRBTree<Integer>();
int[] a = {10,20,30,40,50,60,70,80,90};
//紅黑樹新增測試
for(int i=0;i<a.length;i++) {
tree.insert(a[i]);
}
System.out.print("前序遍歷: ");
tree.preOrder();
System.out.print("\n中序遍歷: ");
tree.inOrder();
System.out.print("\n後序遍歷: ");
tree.postOrder();
System.out.println();
tree.print();
System.out.print("\n輸入要刪除的節點:");
Scanner scan = new Scanner(System.in);
int key = scan.nextInt();
//紅黑樹刪除測試
tree.delete(key);
System.out.println();
tree.print();
}
}
public void leftRonate(RBNode<T> x) {
RBNode<T> y = x.rightChild;
if(y.leftChild!=null) {
y.leftChild.parent = x;
}
x.rightChild = y.leftChild;
y.leftChild = x;
y.parent = x.parent;
if(x.parent!=null) {
if(x.parent.leftChild == x) {
x.parent.leftChild = y;
}else {
x.parent.rightChild = y;
}
}else {
this.mroot = y;
}
x.parent = y;
}
//對某個節點進行右旋
public void rightRonate(RBNode<T> x) {
RBNode<T> y = x.leftChild;
if(y.rightChild!=null) {
y.rightChild.parent = x;
}
y.parent = x.parent;
x.leftChild = y.rightChild;
y.rightChild = x;
if(x.parent!=null) {
if(x.parent.leftChild == x) {
x.parent.leftChild = y;
}else {
x.parent.rightChild = y;
}
}else {
this.mroot = y;
}
x.parent = y;
}
//紅黑樹新增修復
public void insertFixUp(RBNode<T> node) {
RBNode<T> parent,gparent;
while(((parent = parentOf(node))!=null)&&isRed(parent)) {
gparent = parentOf(parent);
if(gparent.leftChild == parent) {
RBNode<T> uncle = gparent.rightChild;
if(isRed(uncle)){
setBlack(parent);
setBlack(uncle);
setRed(gparent);
node = gparent;
continue;
}else {
if(parent.rightChild == node) {
leftRonate(parent);
RBNode<T> temp = node;
node = parent;
parent = temp;
}
setBlack(parent);
setRed(gparent);
rightRonate(gparent);
}
}else {
RBNode<T> uncle = gparent.leftChild;
if(isRed(uncle)) {
setBlack(parent);
setBlack(uncle);
setRed(gparent);
node = gparent;
continue;
}else {
if(parent.leftChild == node) {
rightRonate(parent);
RBNode<T> temp = node;
node = parent;
parent = temp;
}
setBlack(parent);
setRed(gparent);
leftRonate(gparent);
}
}
}
if(mroot == node) {
setBlack(node);
}
}
//紅黑樹刪除修復
public void deleteFixUp(RBNode<T> node,RBNode<T> parent) {
RBNode<T> other;
while(isBlack(node)&&node!=this.mroot) {
if(parent.leftChild == node) {
other = parent.rightChild;
if(isRed(other)) {
setRed(parent);
setBlack(other);
leftRonate(parent);
continue;
}else {
if(isBlack(other.leftChild)&&isBlack(other.rightChild)) {
setRed(other);
node = parent;
parent = parentOf(node);
}else if(isRed(other.leftChild)&&isBlack(other.rightChild)) {
setRed(other);
setBlack(other.leftChild);
rightRonate(other);
}else if(isRed(other.rightChild)) {
setColor(other,colorOf(parent));
setBlack(parent);
setBlack(other.rightChild);
leftRonate(parent);
break;
}
}
}else {
other = parent.leftChild;
if(isRed(other)) {
setBlack(other);
setRed(parent);
rightRonate(parent);
continue;
}else {
if(isBlack(other.leftChild)&&isBlack(other.rightChild)) {
setRed(other);
node = parent;
parent = parentOf(node);
}else if(isRed(other.rightChild)&&isBlack(other.leftChild)) {
setRed(parent);
setBlack(other.rightChild);
leftRonate(other);
}else if(isRed(other.leftChild)) {
setColor(other, colorOf(parent));
setBlack(parent);
setBlack(other.leftChild);
rightRonate(parent);
break;
}
}
}
}
setBlack(node);
}
//紅黑樹新增操作
public void insert(RBNode<T> node) {
int com;
RBNode<T> x = this.mroot;
RBNode<T> y = null;
while(x!=null) {
y = x;
com = node.key.compareTo(x.key);
if(com<0) {
x=x.leftChild;
}else{
x=x.rightChild;
}
}
node.parent = y;
if(y!=null) {
com = node.key.compareTo(y.key);
if(com<0) {
y.leftChild = node;
}else {
y.rightChild = node;
}
}else {
this.mroot = node;
}
setRed(node);
insertFixUp(node);
}
public void insert(T key) {
RBNode<T> node = new RBNode<T>(BLACK,key,null,null,null);
if(node!=null) {
insert(node);
}
}
//紅黑樹刪除操作
public void delete(RBNode<T> node) {
RBNode<T> child,parent,replace;
boolean color = true;
if(node.leftChild!=null&&node.rightChild!=null) {
replace = successor(node);
parent = parentOf(replace);
child = replace.rightChild;
color = colorOf(replace);
if(node == parentOf(replace)) {
parent = replace;
}else {
if(child!=null) {
setParent(child,parentOf(replace));
}
replace.parent.leftChild = child;
replace.rightChild = node.rightChild;
setParent(node.rightChild,replace);
}
setParent(replace, parentOf(node));
replace.leftChild = node.leftChild;
setParent(node.leftChild,replace);
setColor(replace,colorOf(node));
if(parentOf(node)!=null) {
if(node.parent.leftChild==node) {
node.parent.leftChild = replace;
}else {
node.parent.rightChild = replace;
}
}else {
this.mroot = replace;
}
if(color==BLACK){
deleteFixUp(child, parent);
}
}else {
if(node.leftChild!=null) {
replace = node.leftChild;
}else {
replace = node.rightChild;
}
parent = parentOf(node);
if(parent!=null) {
if(parent.leftChild==node) {
parent.leftChild = replace;
}else {
parent.rightChild = replace;
}
}else {
this.mroot = replace;
}
setParent(replace, parent);
color = colorOf(node);
child = replace;
if(color==BLACK) {
deleteFixUp(child, parent);
}
}
}
public void delete(T key) {
RBNode<T> node;
if((node=search(key,this.mroot))!=null) {
delete(node);
}
}
//前序遍歷
public void preOrder(RBNode<T> node) {
if(node!=null) {
System.out.print(node.key+" ");
preOrder(node.leftChild);
preOrder(node.rightChild);
}
}
public void preOrder() {
preOrder(this.mroot);
}
//中序遍歷
public void inOrder(RBNode<T> node) {
if(node!=null) {
inOrder(node.leftChild);
System.out.print(node.key+" ");
inOrder(node.rightChild);
}
}
public void inOrder() {
inOrder(this.mroot);
}
//後序遍歷
public void postOrder(RBNode<T> node) {
if(node!=null) {
postOrder(node.leftChild);
postOrder(node.rightChild);
System.out.print(node.key+" ");
}
}
public void postOrder() {
postOrder(this.mroot);
}
//列印紅黑樹
public void print(RBNode<T> node,int direction) {
if(node!=null) {
if(direction == 0) {
System.out.printf("%2d(%s) is root\n",node.key,node.color==false?"R":"B");
}else {
System.out.printf("%2d(%s) is %s child 父節點 %2d\n",node.key,node.color==false?"R":"B",direction==-1?"left":"right",node.parent.key);
}
print(node.leftChild,-1);
print(node.rightChild,1);
}
}
public void print() {
print(this.mroot,0);
}
public static void main(String[] args) {
DRBTree<Integer> tree = new DRBTree<Integer>();
int[] a = {10,20,30,40,50,60,70,80,90};
//紅黑樹新增測試
for(int i=0;i<a.length;i++) {
tree.insert(a[i]);
}
System.out.print("前序遍歷: ");
tree.preOrder();
System.out.print("\n中序遍歷: ");
tree.inOrder();
System.out.print("\n後序遍歷: ");
tree.postOrder();
System.out.println();
tree.print();
System.out.print("\n輸入要刪除的節點:");
Scanner scan = new Scanner(System.in);
int key = scan.nextInt();
//紅黑樹刪除測試
tree.delete(key);
System.out.println();
tree.print();
}
}