Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之紅黑樹
概述
從今天開始, 小白我將帶大家開啟 Java 數(shù)據(jù)結(jié)構(gòu) & 算法的新篇章.

紅黑樹
紅黑樹 (Red Black Tree) 是一種自平衡二叉查找樹. 如圖:

紅黑樹的特征:
- 研究紅黑樹的每個(gè)節(jié)點(diǎn)都是由顏色的, 非黑即紅
- 根節(jié)點(diǎn)為黑色
- 每個(gè)葉子節(jié)點(diǎn)都是黑色的
- 如果一個(gè)子節(jié)點(diǎn)是紅色的, 那么它的孩子節(jié)點(diǎn)都是黑色的
- 從任何一個(gè)節(jié)點(diǎn)到葉子節(jié)點(diǎn), 經(jīng)過的黑色節(jié)點(diǎn)是一樣的
紅黑樹的實(shí)現(xiàn)
Node 類
// Node類
private class Node {
public E e;
public Node left;
public Node right;
public boolean color;
// Node構(gòu)造
public Node(E e) {
this.e = e;
this.left = null;
this.right = null;
color = RED;
}
@Override
public String toString() {
return "It is node value is: " + e;
}
}
添加元素
// 添加元素
public Node addElement(Node node, E e) {
if(node == null) {
size++;
return new Node(e);
}
// 判斷元素大小
if(e.compareTo(node.e) < 0) {
// 左添加
node.left = addElement(node.left, e);
} else {
// 右添加
node.right = addElement(node.right, e);
}
// 左旋
if(isRed(node.right) && !isRed(node.left)) {
node = leftRotate(node);
}
// 右旋
if(isRed(node.left) && !isRed(node.left.left)) {
node = rightRotate(node);
}
// 顏色反轉(zhuǎn)
if(isRed(node.right) && !isRed(node.left)) {
flipColors(node);
}
return node;
}
左旋
左旋指的是, 以某個(gè)節(jié)點(diǎn)作為支撐點(diǎn), 其右子節(jié)點(diǎn)變?yōu)樾D(zhuǎn)節(jié)點(diǎn)的父節(jié)點(diǎn), 右子節(jié)點(diǎn)的左子節(jié)點(diǎn)的左字節(jié)點(diǎn)變?yōu)樾D(zhuǎn)節(jié)點(diǎn)的右子節(jié)點(diǎn), 旋轉(zhuǎn)節(jié)點(diǎn)的左子節(jié)點(diǎn)保持不變. 如圖:

// node x
// / \ 左旋轉(zhuǎn) / \
// T1 x ==> node T3
// / \ / \
// T2 T3 T1 T2
private Node leftRotate(Node node) {
Node x = node.right;
// 左旋轉(zhuǎn)
node.right = x.left;
x.left = node;
x.color = node.color;
node.color = RED;
return x;
}
右旋
右旋與左旋相反.
代碼實(shí)現(xiàn):
// node x
// / \ 右旋轉(zhuǎn) / \
// x T2 ==> y node
// / \ / \
// y T1 T1 T2
private Node rightRotate(Node node) {
Node x = node.left;
// 右旋轉(zhuǎn)
node.left = x.right;
x.right = node;
x.color = node.color;
node.color = RED;
return x;
}
完整代碼
public class RBT<E extends Comparable<E>> {
private static final boolean RED = true;
private static final boolean BLACK = true;
// Node類
private class Node {
public E e;
public Node left;
public Node right;
public boolean color;
// Node構(gòu)造
public Node(E e) {
this.e = e;
this.left = null;
this.right = null;
color = RED;
}
@Override
public String toString() {
return "It is node value is: " + e;
}
}
public Node root;
private int size;
public int size() {
return size;
}
// 添加元素
public Node addElement(Node node, E e) {
if(node == null) {
size++;
return new Node(e);
}
// 判斷元素大小
if(e.compareTo(node.e) < 0) {
// 左添加
node.left = addElement(node.left, e);
} else {
// 右添加
node.right = addElement(node.right, e);
}
// 左旋
if(isRed(node.right) && !isRed(node.left)) {
node = leftRotate(node);
}
// 右旋
if(isRed(node.left) && !isRed(node.left.left)) {
node = rightRotate(node);
}
// 顏色反轉(zhuǎn)
if(isRed(node.right) && !isRed(node.left)) {
flipColors(node);
}
return node;
}
// node x
// / \ 左旋轉(zhuǎn) / \
// T1 x ==> node T3
// / \ / \
// T2 T3 T1 T2
private Node leftRotate(Node node) {
Node x = node.right;
// 左旋轉(zhuǎn)
node.right = x.left;
x.left = node;
x.color = node.color;
node.color = RED;
return x;
}
// node x
// / \ 右旋轉(zhuǎn) / \
// x T2 ==> y node
// / \ / \
// y T1 T1 T2
private Node rightRotate(Node node) {
Node x = node.left;
// 右旋轉(zhuǎn)
node.left = x.right;
x.right = node;
x.color = node.color;
node.color = RED;
return x;
}
// 顏色反轉(zhuǎn)
private void flipColors(Node node) {
node.color = RED;
node.left.color = BLACK;
node.right.color = BLACK;
}
// 判斷是否為紅色
private boolean isRed(Node node) {
if(node==null) return BLACK;
return node.color;
}
}
到此這篇關(guān)于Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之紅黑樹的文章就介紹到這了,更多相關(guān)Java 紅黑樹內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java throw Exception實(shí)現(xiàn)異常轉(zhuǎn)換
這篇文章主要介紹了Java throw Exception實(shí)現(xiàn)異常轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
springboot整合spring-retry的實(shí)現(xiàn)示例
本文將結(jié)合實(shí)例代碼,介紹springboot整合spring-retry的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06
Java多線程Callable接口實(shí)現(xiàn)代碼示例
相信大家對(duì)Java編程中如何創(chuàng)建線程已經(jīng)不陌生了,這篇文章就向朋友們介紹實(shí)現(xiàn)callable接口,具體實(shí)例詳見正文。2017-10-10

