红黑树实现
Posted INnoVation-V2
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了红黑树实现相关的知识,希望对你有一定的参考价值。
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; public class RBTree<Key extends Comparable<Key>, Value> { enum color {Red, Black} private Node root; private class Node { private Key key; private Value val; private color color; private Node parent; private Node left_child, right_child; boolean isNIL = false; private Node(Key key, Value val, Node parent) { this.key = key; this.val = val; this.parent = parent; this.color = RBTree.color.Red; this.left_child = new Node(this); this.right_child = new Node(this); } private Node(Node parent) { this.color = RBTree.color.Black; this.isNIL = true; this.parent = parent; } } private void LevelOrder() { int h = 0; int num = 0; ArrayList<Node> t = new ArrayList<Node>(); t.add(root); while (t.size() != 0) { int size = t.size(); h++; System.out.println("第 " + h + " 层"); for (int i = 0; i < size; i++) { Node x = t.get(0); num++; if (x.left_child.parent != x) System.out.println("Left"); if (x.right_child.parent != x) System.out.println("Right"); System.out.print(" " + x.key + "-" + x.color + " "); if (!x.left_child.isNIL) t.add(x.left_child); if (!x.right_child.isNIL) t.add(x.right_child); t.remove(0); } System.out.println(""); } System.out.println("共计" + num + "个数"); } public void Insert(Key key, Value val) { if (root == null) { root = new Node(key, val, null); root.color = color.Black; return; } Node temp = root; while (true) { int cmp = key.compareTo(temp.key); if (cmp < 0) if (!temp.left_child.isNIL) temp = temp.left_child; else { temp.left_child = new Node(key, val, temp); if (conflict(temp.left_child)) Update_Tree(temp.left_child); return; } else if (cmp > 0) { if (!temp.right_child.isNIL) temp = temp.right_child; else { temp.right_child = new Node(key, val, temp); if (conflict(temp.right_child)) Update_Tree(temp.right_child); return; } } else { temp.val = val; return; } } } public void Remove(Key key) { Node temp = root; while (!temp.isNIL) { int cmp = key.compareTo(temp.key); if (cmp > 0) temp = temp.right_child; else if (cmp < 0) temp = temp.left_child; else { if (isRoot(temp) && temp.left_child.isNIL && temp.right_child.isNIL) { root = null; return; } Node parent = temp.parent; color t = temp.color; if (!temp.left_child.isNIL && !temp.right_child.isNIL) {//当待删除节点的左右兄弟节点都不为空 Node x = temp.right_child;//找出后继节点 while (!x.left_child.isNIL) x = x.left_child; temp.key = x.key; temp.val = x.val; parent = x.parent; t = x.color; if (isLeftChild(x)) { parent.left_child = x.right_child; parent.left_child.parent = parent; temp = parent.left_child; } else { parent.right_child = x.right_child; parent.right_child.parent = parent; temp = parent.right_child; } } else if (!temp.left_child.isNIL) {//当右兄弟为空 if (isLeftChild(temp)) { if (isRoot(temp)) { temp.key = temp.left_child.key; temp.val = temp.left_child.val; temp.left_child = temp.left_child.left_child; temp.left_child.parent = temp; } else { parent.left_child = temp.left_child; temp.left_child.parent = parent; temp = parent.left_child; } } else { parent.right_child = temp.left_child; temp.left_child.parent = parent; temp = parent.right_child; } } else if (!temp.right_child.isNIL) {//当左兄弟为空 if (isLeftChild(temp)) { if (isRoot(temp)) { temp.key = temp.right_child.key; temp.val = temp.right_child.val; temp.right_child = temp.right_child.left_child; temp.right_child.parent = temp; } else { parent.left_child = temp.right_child; temp.right_child.parent = parent; temp = parent.left_child; } } else { parent.right_child = temp.right_child; temp.right_child.parent = parent; temp = parent.right_child; } } else { //当左右兄弟都为空 if (isLeftChild(temp)) if (!isRoot(temp)) parent.left_child = temp.left_child; else parent.right_child = temp.left_child; temp.left_child.parent = parent; temp = temp.left_child; } if (t == color.Black) if (temp.color == color.Red) temp.color = color.Black; else Update_Tree_Remove(temp); } } while (root.parent != null) root = root.parent; } private void Update_Tree_Remove(Node temp) { if (isRoot(temp)) { if (!temp.left_child.isNIL && temp.left_child.color == color.Black) temp.left_child.color = color.Red; else temp.right_child.color = color.Red; return; } Node parent = temp.parent, uncle; if (isLeftChild(temp)) { uncle = parent.right_child; if (uncle.color == color.Black) { //叔叔是黑色 if (uncle.left_child.color == color.Red || uncle.right_child.color == color.Red) { //CASE 1 叔叔有一个孩子是红色的 color c = parent.color; if (uncle.left_child.color == color.Red) { //若叔叔的左孩子是红的 Node t = uncle.left_child; temp = connect34(false, t, parent, uncle, parent, temp, t.left_child, t.right_child, uncle.right_child); System.out.print(""); } else { //若叔叔的右孩子是红的 Node t = uncle.right_child; temp = connect34(false, uncle, parent, t, parent, temp, uncle.left_child, t.left_child, t.right_child); } temp.color = c; } else if (parent.color == color.Red) { //CASE 2 父节点是红色 uncle.color = color.Red; parent.color = color.Black; } else { //叔叔黑色,父节点也是黑色,父节点所有孩子都是黑色 uncle.color = color.Red; if (parent.parent != null) Update_Tree_Remove(parent); } } else { //叔叔是红色 parent.right_child = uncle.left_child; parent.right_child.parent = parent; uncle.left_child = parent; uncle.parent = parent.parent; if (parent.parent != null) if (isLeftChild(parent)) parent.parent.left_child = uncle; else parent.parent.right_child = uncle; parent.parent = uncle; parent.color = color.Red; uncle.color = color.Black; Update_Tree_Remove(temp); } } else { //反转情况 uncle = parent.left_child; if (uncle.color == color.Black) { if (uncle.left_child.color == color.Red || uncle.right_child.color == color.Red) { color c = parent.color; if (uncle.left_child.color == color.Red) { Node t = uncle.left_child; temp = connect34(false, uncle, t, parent, parent, t.left_child, t.right_child, uncle.right_child, temp); } else { Node t = uncle.right_child; temp = connect34(false, t, uncle, parent, parent, uncle.left_child, t.left_child, t.right_child, temp); } temp.color = c; } else if (parent.color == color.Red) { uncle.color = color.Red; parent.color = color.Black; } else { uncle.color = color.Red; if (parent.parent != null) Update_Tree_Remove(parent); } } else { parent.left_child = uncle.right_child; parent.left_child.parent = parent; uncle.right_child = parent; uncle.parent = parent.parent; if (parent.parent != null) if (isLeftChild(parent)) parent.parent.left_child = uncle; else parent.parent.right_child = uncle; parent.parent = uncle; parent.color = color.Red; uncle.color = color.Black; Update_Tree_Remove(temp); } } } private boolean conflict(Node p) { return p.color == p.parent.color; } private void Recolor(Node p) { p.color = color.Red; p.left_child.color = color.Black; p.right_child.color = color.Black; } private Node connect34(boolean allblack, Node root, Node left, Node right, Node parent, Node child_1, Node child_2, Node child_3, Node child_4) { if (parent.parent != null) { if (isLeftChild(parent)) parent.parent.left_child = root; else parent.parent.right_child = root; root.parent = parent.parent; } else root.parent = null; root.left_child = left; left.parent = root; root.right_child = right; right.parent = root; left.left_child = child_1; child_1.parent = left; left.right_child = child_2; child_2.parent = left; right.left_child = child_3; child_3.parent = right; right.right_child = child_4; child_4.parent = right; if (!allblack) Recolor(root); else { root.color = color.Black; root.left_child.color = color.Red; root.right_child.color = color.Red; } return root; } private boolean isRoot(Node temp) { return temp.parent == null; } private boolean isLeftChild(Node temp) { if (isRoot(temp)) return true; return temp.parent.left_child == temp; } private void Update_Tree(Node temp) { boolean allblack; while (!isRoot(temp) && temp.parent.color == color.Red && temp.color == color.Red) { Node parent = temp.parent, grandparent = temp.parent.parent; if (parent == grandparent.left_child) { //CASE 1 if (grandparent.right_child.color == color.Red) { Recolor(grandparent); temp = grandparent; } else if (temp == parent.right_child) //CASE 2 { allblack = parent.left_child.color == color.Black && temp.left_child.color == color.Black && temp.right_child.color == color.Black; temp = connect34(allblack, temp, parent, grandparent, grandparent, parent.left_child, temp.left_child, temp.right_child, grandparent.right_child); } else { //CASE 3 allblack = parent.right_child.color == color.Black && temp.left_child.color == color.Black && temp.right_child.color == color.Black; temp = connect34(allblack, parent, temp, grandparent, grandparent, temp.left_child, temp.right_child, parent.right_child, grandparent.right_child); } } else { //Reverse situation if (grandparent.left_child.color == color.Red) { Recolor(grandparent); temp = grandparent; } else if (temp == parent.left_child) { allblack = parent.right_child.color == color.Black && temp.left_child.color == color.Black && temp.right_child.color == color.Black; temp = connect34(allblack, temp, grandparent, parent, grandparent, grandparent.left_child, temp.left_child, temp.right_child, parent.right_child); } else { allblack = parent.left_child.color == color.Black && temp.left_child.color == color.Black && temp.right_child.color == color.Black; temp = connect34(allblack, parent, grandparent, temp, grandparent, grandparent.left_child, parent.left_child, temp.left_child, temp.right_child); } } } if (isRoot(temp)) { root = temp; root.color = color.Black; } } public static void main(String args[]) { RBTree<Integer, Integer> RBT = new RBTree<>(); ArrayList<Integer> z = new ArrayList<>(); try { FileReader fw = new FileReader("/home/innovation/文档/num"); BufferedReader br = new BufferedReader(fw); String x; while ((x = br.readLine()) != null) z.add(Integer.parseInt(x)); fw.close(); } catch (IOException e) { e.printStackTrace(); } // while (z.size() < 10) { // int x = (int) (Math.random() * 20); // if (!z.contains(x)) // z.add(x); // } for (int i = 0; i < z.size(); i++) { // System.out.println(z.get(i)); RBT.Insert(z.get(i), i); } // RBT.LevelOrder(); for (int i = 0; i < 20; i++) { System.out.println(z.get(i)); if (z.get(i) == 8) System.out.println(" "); RBT.Remove(z.get(i)); RBT.LevelOrder(); } System.out.println(" "); } }
以上是关于红黑树实现的主要内容,如果未能解决你的问题,请参考以下文章