Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之紅黑樹
概述
從今天開始, 小白我將帶大家開啟 Java 數(shù)據(jù)結(jié)構(gòu) & 算法的新篇章.
紅黑樹
紅黑樹 (Red Black Tree) 是一種自平衡二叉查找樹. 如圖:
紅黑樹的特征:
- 研究紅黑樹的每個節(jié)點(diǎn)都是由顏色的, 非黑即紅
- 根節(jié)點(diǎn)為黑色
- 每個葉子節(jié)點(diǎn)都是黑色的
- 如果一個子節(jié)點(diǎn)是紅色的, 那么它的孩子節(jié)點(diǎn)都是黑色的
- 從任何一個節(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; }
左旋
左旋指的是, 以某個節(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java throw Exception實(shí)現(xiàn)異常轉(zhuǎn)換
這篇文章主要介紹了Java throw Exception實(shí)現(xiàn)異常轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04springboot整合spring-retry的實(shí)現(xiàn)示例
本文將結(jié)合實(shí)例代碼,介紹springboot整合spring-retry的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06Java多線程Callable接口實(shí)現(xiàn)代碼示例
相信大家對Java編程中如何創(chuàng)建線程已經(jīng)不陌生了,這篇文章就向朋友們介紹實(shí)現(xiàn)callable接口,具體實(shí)例詳見正文。2017-10-10