大纲
通过java简单实现红黑树打印红黑树结构(网上找的一个方法)
通过java简单实现红黑树
package com
.example
.demo
.rbt
;
import lombok
.Data
;
public class RBTree<K
extends Comparable<K>, V
> {
public static final boolean RED
= true;
public static final boolean BLACK
= false;
private RBNode
<K, V> root
;
private RBNode
<K, V> getParentNode(RBNode
<K, V> node
){
if (node
!= null
) {
return node
.parent
;
}
return null
;
}
private boolean isRed(RBNode
<K, V> node
){
return node
!= null
&& node
.color
;
}
private boolean isBlack(RBNode
<K, V> node
){
return node
!= null
&& !node
.color
;
}
private void setRed(RBNode
<K, V> node
){
if (node
!= null
) {
node
.setColor(RED
);
}
}
private void setBlack(RBNode
<K, V> node
){
if (node
!= null
) {
node
.setColor(BLACK
);
}
}
private void rightSpin(RBNode
<K, V> node
){
RBNode
<K, V> pN
= node
.parent
;
RBNode
<K, V> lN
= node
.left
;
node
.left
= lN
.right
;
if (lN
.right
!= null
) {
lN
.right
.parent
= node
;
}
node
.parent
= lN
;
lN
.right
= node
;
if (pN
!= null
) {
lN
.parent
= pN
;
if (pN
.left
== node
) {
pN
.left
= lN
;
}else {
pN
.right
= lN
;
}
}else {
this.root
= lN
;
}
}
private void leftSpin(RBNode
<K, V> node
){
RBNode
<K, V> pN
= node
.parent
;
RBNode
<K, V> rN
= node
.right
;
node
.right
= rN
.left
;
if (rN
.left
!= null
) {
rN
.left
.parent
= node
;
}
node
.parent
= rN
;
rN
.left
= node
;
rN
.parent
= pN
;
if (pN
!= null
) {
if (pN
.left
== node
) {
pN
.left
= rN
;
}else {
pN
.right
= rN
;
}
}else {
this.root
= rN
;
}
}
public void inOrderPrint(){
System
.out
.print("中序遍历:");
inOrderPrint(this.root
);
}
public RBNode
<K, V> getRoot(){
return this.root
;
}
private void inOrderPrint(RBNode
<K, V> node
){
if (node
!= null
) {
inOrderPrint(node
.left
);
System
.out
.print(node
.key
+ " ");
inOrderPrint(node
.right
);
}
}
public RBNode
<K, V> get(K key
){
return getNode(this.root
, key
);
}
private RBNode
<K, V> getNode(RBNode
<K, V> node
, K key
){
while (node
!= null
){
K k
= node
.key
;
if (key
.compareTo(k
) > 0) {
node
= node
.right
;
}else if(key
.compareTo(k
) < 0){
node
= node
.left
;
}else {
return node
;
}
}
return null
;
}
public void add(K key
, V value
){
RBNode
<K, V> node
= new RBNode<>(RED
, key
, value
);
addNode(node
);
}
private void addNode(RBNode
<K, V> node
){
RBNode
<K, V> parent
= null
;
RBNode
<K, V> temp
= this.root
;
while (temp
!= null
){
parent
= temp
;
K k
= temp
.key
;
int i
= node
.key
.compareTo(k
);
if (i
> 0) {
temp
= temp
.right
;
} else if (i
< 0) {
temp
= temp
.left
;
} else {
temp
.value
= node
.value
;
return;
}
}
node
.parent
= parent
;
if (parent
!= null
) {
int i
= node
.key
.compareTo(parent
.key
);
if (i
> 0) {
parent
.right
= node
;
}else {
parent
.left
= node
;
}
}else {
this.root
= node
;
}
selfBalance(node
);
}
private void selfBalance(RBNode
<K, V> node
){
if (this.root
== node
) {
setBlack(node
);
return;
}
RBNode
<K, V> pN
= getParentNode(node
);
RBNode
<K, V> gpN
= getParentNode(pN
);
if (isRed(pN
)) {
RBNode
<K, V> uN
;
if (gpN
.left
== pN
) {
uN
= gpN
.right
;
}else {
uN
= gpN
.left
;
}
if (isRed(uN
)) {
setBlack(pN
);
setBlack(uN
);
setRed(gpN
);
selfBalance(gpN
);
return;
}
if (uN
== null
|| isBlack(uN
)) {
if (pN
== gpN
.left
) {
if (node
== pN
.left
) {
setBlack(pN
);
setRed(gpN
);
rightSpin(gpN
);
}else {
leftSpin(pN
);
selfBalance(pN
);
}
}else {
if (node
== node
.parent
.left
) {
rightSpin(pN
);
selfBalance(pN
);
}else {
setBlack(pN
);
setRed(gpN
);
leftSpin(gpN
);
}
}
}
}
}
@Data
static class RBNode<K
extends Comparable<K>, V
>{
private RBNode
<K, V> parent
;
private RBNode
<K, V> right
;
private RBNode
<K, V> left
;
private boolean color
;
private K key
;
private V value
;
public RBNode() {
}
public RBNode(boolean color
, K key
, V value
) {
this.color
= color
;
this.key
= key
;
this.value
= value
;
}
@Override
public String
toString() {
return "RBNode{" +
"color=" + color
+
", key=" + key
+
", value=" + value
+
'}';
}
}
}
打印红黑树结构(网上找的一个方法)
package com
.example
.demo
.rbt
;
import java
.util
.ArrayList
;
import java
.util
.Collections
;
import java
.util
.List
;
import java
.util
.Random
;
public class RBTreePrinterTest {
public static <K
extends Comparable<K>, V
> void printNode(RBTree
.RBNode
<K, V> root
) {
int maxLevel
= RBTreePrinterTest
.maxLevel(root
);
printNodeInternal(Collections
.singletonList(root
), 1, maxLevel
);
}
private static <K
extends Comparable<K>, V
> void printNodeInternal(List
<RBTree
.RBNode
<K, V>> nodes
, int level
, int maxLevel
) {
if (nodes
.isEmpty() || RBTreePrinterTest
.isAllElementsNull(nodes
)) {
return;
}
int floor
= maxLevel
- level
;
int endgeLines
= (int) Math
.pow(2, (Math
.max(floor
- 1, 0)));
int firstSpaces
= (int) Math
.pow(2, (floor
)) - 1;
int betweenSpaces
= (int) Math
.pow(2, (floor
+ 1)) - 1;
RBTreePrinterTest
.printWhitespaces(firstSpaces
);
List
<RBTree
.RBNode
<K, V>> newNodes
= new ArrayList<>();
for (RBTree
.RBNode
<K, V> node
: nodes
) {
if (node
!= null
) {
String key
= node
.isColor() ? "\033[31;4m" + node
.getKey() + "\033[0m" : node
.getKey().toString();
System
.out
.print(key
);
newNodes
.add(node
.getLeft());
newNodes
.add(node
.getRight());
} else {
newNodes
.add(null
);
newNodes
.add(null
);
System
.out
.print(" ");
}
RBTreePrinterTest
.printWhitespaces(betweenSpaces
);
}
System
.out
.println();
for (int i
= 1; i
<= endgeLines
; i
++) {
for (RBTree
.RBNode
<?, ?> node
: nodes
) {
RBTreePrinterTest
.printWhitespaces(firstSpaces
- i
);
if (node
== null
) {
RBTreePrinterTest
.printWhitespaces(endgeLines
+ endgeLines
+ i
+ 1);
continue;
}
if (node
.getLeft() != null
) {
System
.out
.print("/");
} else {
RBTreePrinterTest
.printWhitespaces(1);
}
RBTreePrinterTest
.printWhitespaces(i
+ i
- 1);
if (node
.getRight() != null
) {
System
.out
.print("\\");
} else {
RBTreePrinterTest
.printWhitespaces(1);
}
RBTreePrinterTest
.printWhitespaces(endgeLines
+ endgeLines
- i
);
}
System
.out
.println("");
}
printNodeInternal(newNodes
, level
+ 1, maxLevel
);
}
private static void printWhitespaces(int count
) {
for (int i
= 0; i
< count
; i
++) {
System
.out
.print(" ");
}
}
private static <K
extends Comparable<K>, V
> int maxLevel(RBTree
.RBNode
<K, V> node
) {
if (node
== null
) {
return 0;
}
return Math
.max(RBTreePrinterTest
.maxLevel(node
.getLeft()), RBTreePrinterTest
.maxLevel(node
.getRight())) + 1;
}
private static <K
extends Comparable<K>, V
> boolean isAllElementsNull(List
<RBTree
.RBNode
<K, V>> list
) {
for (Object object
: list
) {
if (object
!= null
) {
return false;
}
}
return true;
}
public static void main(String
[] args
) {
RBTree
<Integer, Object> rbTree
= new RBTree<>();
new Random().ints(15, 1, 50).forEach(k
-> rbTree
.add(k
, null
));
RBTreePrinterTest
.printNode(rbTree
.getRoot());
rbTree
.inOrderPrint();
}
}
实现效果
红色字体需要安装IDEA插件 ANSI Highlighter
通过控制台输出各种颜色的字符
转载请注明原文地址:https://ipadbbs.8miu.com/read-24115.html