資料結構-紅黑樹擴張-區間樹
阿新 • • 發佈:2019-02-04
package com.data.struct; public class IntervalTree { private Node root; //private Node nil; public IntervalTree(int [][]data){ for(int i=0;i<data.length;i++){ Node node=new Node(); node.setLow(data[i][0]); node.setHigh(data[i][1]); insert(node); } } /** * 中序遍歷 */ public void inorderTreeWalk(){ innerInorderTreeWalk(root); System.out.println(); } /** * 中序遍歷 */ private void innerInorderTreeWalk(Node node){ if(node!=null){ innerInorderTreeWalk(node.left); System.out.print("-->{"+node.low+","+node.high+"}"); innerInorderTreeWalk(node.right); } } /** * 先序遍歷 */ public void preorderWalk(){ System.out.println(" "+((root.color==Node.RED?"R":"B")+"{"+root.low+","+root.high+"-"+root.max+"}")); innerPreorderWalk(root,1); System.out.println(); } private void innerPreorderWalk(Node node,int depth){ if(node!=null){ if(node.left!=null){ for(int i=6-depth*2;i>0;i--){ System.out.print(" "); } System.out.print((node.left.color==Node.RED?"R":"B")+"{"+node.left.low+","+node.left.high+"-"+node.left.max+"},{"+node.low+","+node.high+"}"); }else{ System.out.print(" "); } if(node.right!=null){ System.out.print(" "); System.out.print((node.right.color==Node.RED?"R":"B")+"{"+node.right.low+","+node.right.high+"-"+node.right.max+"},{"+node.low+","+node.high+"}"); }else{ System.out.print(" "); } if(node.left!=null||node.right!=null){ System.out.println(); } innerPreorderWalk(node.left,depth+1); innerPreorderWalk(node.right,depth+1); } } /** * 後續遍歷 */ public void postorderWalk(){ innerPostorderWalk(root); System.out.println(); } private void innerPostorderWalk(Node node){ innerPostorderWalk(node.left); innerPostorderWalk(node.right); System.out.print("-->{"+node.low+","+node.high+"}"); } /** * 查詢值為value的節點 * @param value * @return */ public Node search(int low,int high){ if(low<high){ int tmp=low; low=high; high=tmp; } return innerSearch(root,low,high); } private Node innerSearch(Node node,int low,int high){ Node x=root; while(x!=null&&!(low<=x.high&&x.low<=high)){ if(x.left!=null&&x.left.max>=low){ x=x.left; }else{ x=x.right; } } return x; } /** * 返回最小值節點 * @return */ public Node minimum(){ return innerMinimum(root); } private Node innerMinimum(Node node){ if(node.left!=null){ return innerMinimum(node.left); } return node; } /** * 返回最大值節點 * @return */ public Node maximum(){ return innerMaximum(root); } private Node innerMaximum(Node node){ if(node.right!=null){ return innerMaximum(node.right); } return node; } /** * 返回給定節點的後繼結點 * @param node * @return */ public Node successor(Node node){ if(node.right!=null){ return innerMinimum(node.right); } Node y=node.parent; while(y!=null&&y.right==node){ node=y; y=y.parent; } return y; } /** * 插入 * @param node */ private void insert(Node node){ if(node.low>node.high){ int tmp=node.low; node.low=node.high; node.high=tmp; } Node y=null; Node x=root; while(x!=null){ y=x; if(node.low<x.low){ x=x.left; }else{ x=x.right; } } node.parent=y; if(y==null){ root=node; }else if(y.low>node.low){ y.left=node; }else{ y.right=node; } node.max=node.high; Node z=node; while(z!=null){ if(z.left==null&&z.right!=null){ z.max=Math.max(z.right.max, z.high); }else if(z.right==null&&z.left!=null){ z.max=Math.max(z.left.max, z.high); }else if(z.right==null&&z.left==null){ z.max=z.high; }else{ z.max=Math.max(Math.max(z.high, z.left.max),z.right.max); } z=z.parent; } root.parent=null; node.color=Node.RED; preorderWalk(); insertFixUp(node); preorderWalk(); } /** * 插入修復顏色 * @param node */ private void insertFixUp(Node node){ if(node.parent==null){ node.color=Node.BLACK; }else if(node.parent.parent==null){ node.color=Node.RED; }else { while(node.parent==null||node.parent.color==Node.RED){ if(node.parent==null){ node.color=Node.BLACK; return; }else if(node.parent==node.parent.parent.left){ Node y=node.parent.parent.right; if(y==null||y.color==Node.RED){ node.parent.color=Node.BLACK; if(y!=null){ y.color=Node.BLACK; }else{ node.parent.parent.color=Node.RED; rightRotate(node.parent.parent); return; } node.parent.parent.color=Node.RED; node=node.parent.parent; }else if(node==node.parent.right){ node=node.parent; leftRotate(node); }else{ node.parent.color=Node.BLACK; node.parent.parent.color=Node.RED; rightRotate(node.parent.parent); } }else{ Node y=node.parent.parent.left; if(y==null||y.color==Node.RED){ node.parent.color=Node.BLACK; if(y!=null){ y.color=Node.BLACK; }else{ node.parent.parent.color=Node.RED; leftRotate(node.parent.parent); return; } node.parent.parent.color=Node.RED; node=node.parent.parent; }else if(node==node.parent.left){ node=node.parent; rightRotate(node); }else{ node.parent.color=Node.BLACK; node.parent.parent.color=node.RED; leftRotate(node.parent.parent); } } } } } public void insert(int low,int high){ Node node=new Node(); node.setLow(low); node.setHigh(high); insert(node); } private void delete(Node node){ Node y=node; int yoc=y.color; Node x; if(node.left==null&&node.right!=null){ x=node.right; transplant(node, node.right); Node z=x; while(z!=null){ if(z.left==null&&z.right!=null){ z.max=Math.max(z.right.max, z.high); }else if(z.right==null&&z.left!=null){ z.max=Math.max(z.left.max, z.high); }else if(z.right==null&&z.left==null){ z.max=z.high; }else{ z.max=Math.max(Math.max(z.high, z.left.max),z.right.max); } z=z.parent; } }else if(node.right==null&&node.left!=null){ x=node.left; transplant(node, node.left); Node z=x; while(z!=null){ if(z.left==null&&z.right!=null){ z.max=Math.max(z.right.max, z.high); }else if(z.right==null&&z.left!=null){ z.max=Math.max(z.left.max, z.high); }else if(z.right==null&&z.left==null){ z.max=z.high; }else{ z.max=Math.max(Math.max(z.high, z.left.max),z.right.max); } z=z.parent; } }else if(node.left==null&&node.right==null){ if(node.parent==null){ root=null; System.out.println("root is null"); return; } x=node.parent; Node z=x; if(node==node.parent.left){ node.parent.left=null; while(z!=null){ if(z.left==null&&z.right!=null){ z.max=Math.max(z.right.max, z.high); }else if(z.right==null&&z.left!=null){ z.max=Math.max(z.left.max, z.high); }else if(z.right==null&&z.left==null){ z.max=z.high; }else{ z.max=Math.max(Math.max(z.high, z.left.max),z.right.max); } z=z.parent; } if(x.color==Node.RED){ leftRotate(x); preorderWalk(); return; }else if(x.color==Node.BLACK&&node.color==Node.BLACK){ x=node.parent.right; deleteFixUp(x); return; } }else{ node.parent.right=null; while(z!=null){ if(z.left==null&&z.right!=null){ z.max=Math.max(z.right.max, z.high); }else if(z.right==null&&z.left!=null){ z.max=Math.max(z.left.max, z.high); }else if(z.right==null&&z.left==null){ z.max=z.high; }else{ z.max=Math.max(Math.max(z.high, z.left.max),z.right.max); } z=z.parent; } if(x.color==Node.RED){ rightRotate(x); preorderWalk(); return; }else if(x.color==Node.BLACK&&node.color==Node.BLACK){ x=node.parent.left; deleteFixUp(x); return; } } }else{ y=innerMinimum(node.right); yoc=y.color; if(y.parent!=node){ Node z=y.right; transplant(y, y.right); while(z!=null){ if(z.left==null&&z.right!=null){ z.max=Math.max(z.right.max, z.high); }else if(z.right==null&&z.left!=null){ z.max=Math.max(z.left.max, z.high); }else if(z.right==null&&z.left==null){ z.max=z.high; }else{ z.max=Math.max(Math.max(z.high, z.left.max),z.right.max); } z=z.parent; } y.right=node.right; y.right.parent=y; } Node z=y; transplant(node, y); while(z!=null){ if(z.left==null&&z.right!=null){ z.max=Math.max(z.right.max, z.high); }else if(z.right==null&&z.left!=null){ z.max=Math.max(z.left.max, z.high); }else if(z.right==null&&z.left==null){ z.max=z.high; }else{ z.max=Math.max(Math.max(z.high, z.left.max),z.right.max); } z=z.parent; } x=y.right; y.left=node.left; y.left.parent=y; y.color=node.color; if(x==null){ preorderWalk(); y.color=Node.RED; if(y.left!=null){ y.left.color=Node.BLACK; rightRotate(y); }else if(y.right!=null){ y.right.color=Node.RED; leftRotate(y); }else{ y.color=Node.RED; } preorderWalk(); return; } } preorderWalk(); if(yoc==Node.BLACK){ deleteFixUp(x); preorderWalk(); } } private void deleteFixUp(Node node){ if(node==null){ } while(node!=root&&node.color==Node.BLACK){ Node w; if(node==node.parent.left){ w=node.parent.right; if(w.color==Node.RED){ w.color=Node.BLACK; node.parent.color=Node.RED; leftRotate(node.parent); w=node.parent.right; } if(w.left.color==Node.BLACK&&w.right.color==Node.BLACK){ w.color=Node.RED; node=node.parent; }else if(w.right.color==Node.BLACK){ w.left.color=Node.BLACK; w.color=Node.RED; rightRotate(w); w=node.parent.right; } w.color=node.parent.color; node.parent.color=Node.BLACK; w.right.color=Node.BLACK; leftRotate(node.parent); node=root; }else{ w=node.parent.left; if(w.color==Node.RED){ w.color=Node.BLACK; node.parent.color=Node.RED; rightRotate(node.parent); w=node.parent.left; } if(w.right.color==Node.BLACK&&w.left.color==Node.BLACK){ w.color=Node.RED; node=node.parent; }else if(w.left.color==Node.BLACK){ w.left.color=Node.BLACK; w.color=Node.RED; leftRotate(w); w=node.parent.left; } w.color=node.parent.color; node.parent.color=Node.BLACK; w.left.color=Node.BLACK; rightRotate(node.parent); node=root; } } node.color=Node.BLACK; } /** * 左旋轉 * @param node */ private void leftRotate(Node node){ Node y=node.right; node.right=y.left; if(y.left!=null){ y.left.parent=node; } y.parent=node.parent; if(node.parent==null){ root=y; }else if(node==node.parent.left){ node.parent.left=y; }else{ node.parent.right=y; } y.left=node; node.parent=y; if(node.left==null&&node.right!=null){ node.max=Math.max(node.right.max, node.high); }else if(node.right==null&&node.left!=null){ node.max=Math.max(node.left.max, node.high); }else if(node.right==null&&node.left==null){ node.max=node.high; }else{ node.max=Math.max(Math.max(node.high, node.left.max),node.right.max); } if(y.left==null&&y.right!=null){ y.max=Math.max(y.right.max, y.high); }else if(y.right==null&&y.left!=null){ y.max=Math.max(y.left.max, y.high); }else if(y.right==null&&y.left==null){ y.max=y.high; }else{ y.max=Math.max(Math.max(y.high, y.left.max),y.right.max); } } /** * 右旋轉 * @param node */ private void rightRotate(Node node){ Node y=node.left; node.left=y.right; if(y.right!=null){ y.right.parent=node; } y.parent=node.parent; if(node.parent==null){ root=y; }else if(node==node.parent.left){ node.parent.left=y; }else{ node.parent.right=y; } y.right=node; node.parent=y; if(node.left==null&&node.right!=null){ node.max=Math.max(node.right.max, node.high); }else if(node.right==null&&node.left!=null){ node.max=Math.max(node.left.max, node.high); }else if(node.right==null&&node.left==null){ node.max=node.high; }else{ node.max=Math.max(Math.max(node.high, node.left.max),node.right.max); } if(y.left==null&&y.right!=null){ y.max=Math.max(y.right.max, y.high); }else if(y.right==null&&y.left!=null){ y.max=Math.max(y.left.max, y.high); }else if(y.right==null&&y.left==null){ y.max=y.high; }else{ y.max=Math.max(Math.max(y.high, y.left.max),y.right.max); } } private void transplant(Node u,Node v){ if(u.parent==null){ root=v; }else if(u==u.parent.left){ u.parent.left=v; }else{ u.parent.right=v; } if(v!=null){ v.parent=u.parent; } } /** * 刪除節點 * @param value */ public void delete(int low,int high){ delete(search(low,high)); } private static class Node{ public static final int RED=1; public static final int BLACK=2; private Node left; private Node right; private Node parent; private int low; private int high; private int color; private int max; public Node getLeft() { return left; } public void setLeft(Node left) { this.left = left; } public Node getRight() { return right; } public void setRight(Node right) { this.right = right; } public Node getParent() { return parent; } public void setParent(Node parent) { this.parent = parent; } public int getColor() { return color; } public void setColor(int color) { this.color = color; } public int getLow() { return low; } public void setLow(int low) { this.low = low; } public int getHigh() { return high; } public void setHigh(int high) { this.high = high; } public int getMax() { return max; } public void setMax(int max) { this.max = max; } } public static void main(String[] args) { int [][] data=new int[][]{{1,2},{3,5},{2,4},{6,11},{3,9},{9,15},{1,10},{10,12},{11,16}}; IntervalTree tree=new IntervalTree(data); tree.inorderTreeWalk(); System.out.println("==========="); System.out.println(tree.search(9, 15).low+","+tree.search(9, 15).high); tree.delete(9, 15); System.out.println(tree.search(11, 16).low+","+tree.search(11, 16).high); tree.delete(11, 16); } }