4000 Java基础 - 节点自平衡树(Size Balanced Tree,简称SBT)
2016-12-09 16:08
465 查看
package com.yc.tree; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.List; public class SizeBalancedTree <T extends Comparable<T>>{ public class Node{ //data域:存放数据项 T data; //size域:存放树的大小(节点数目) int size; Node parent; Node left; Node right; public Node(T data, int size, Node parent, Node left, Node right){ this.data = data; this.size = size; this.parent = parent; this.left = left; this.right = right; } public String toString(){ return "[data="+data+",size="+size+"]"; } } //根节点 private Node root; public Node root(){ return root; } public SizeBalancedTree(){ root = null; } public SizeBalancedTree(T data){ root = new Node(data, 1, null, null, null); } /** * 往根为root的树中插入data * @param data * @param root */ public void insert(T data){ if(root == null){ //如果根为空 root = new Node(data, 1, null, null, null); }else{ Node current = root; Node parent = null; int result = 0; while(current != null){ parent = current; result = data.compareTo(current.data); if(result > 0){ current = current.right; }else{ current = current.left; } } Node newNode = new Node(data, 1, parent, null, null); if(result > 0){ parent.right = newNode; }else{ parent.left = newNode; } ancestorAdd1(newNode); maintain(newNode); } } private void ancestorAdd1(Node node){ Node current = node; while(current.parent != null){ current.parent.size += 1; current = current.parent; } } private void ancestorminu1(Node node){ Node current = node; while(current.parent != null){ current.parent.size -= 1; current = current.parent; } } private boolean trueOrFalse(Node node){ Node current = node; while(current != null){ if(current == root.left){ return false; }else if(current == root.right){ return true; } current = current.parent; } return false; } private void maintain(Node node) { //node为新添加的节点 if(root == node.parent){ return; }else{ maintainHelp(root, trueOrFalse(node)); } } private void maintainHelp(Node node, boolean flag){ //传过来的node为新添加的节点 if(node != null){ /*Node t = node; Node l = t.left; Node r = t.right;*/ if(!flag && node.left != null){ //左边 if((node.right == null && node.left.left != null ) || (node.left.left != null && node.left.left.size > node.right.size)){ //case1 right_rot(node); } else if((node.right == null && node.left.right != null ) || (node.left.right != null && node.left.right.size > node.right.size)){//case2 left_rot(node.left); right_rot(node); }else{ return; } maintainHelp(node.left, false); maintainHelp(node.right, true); maintainHelp(node, false); maintainHelp(node, true); }else if(flag && node.right != null){ //右边 if((node.left == null && node.right.left != null ) || (node.right.left != null && node.right.left.size > node.left.size)){ //case2* right_rot(node.right); left_rot(node); } else if((node.left == null && node.right.right != null ) || (node.right.right != null && node.right.right.size > node.left.size)){//case1* left_rot(node); }else{ return; } maintainHelp(node.left, false); maintainHelp(node.right, true); maintainHelp(node, false); maintainHelp(node, true); } } } /** * 从根为node的树中删除数据元素为data的节点 * @param node * @param data */ public void remove(Node node, T data){ Node del = find(data); if(del != null){ boolean what = trueOrFalse(del); if(del.left == null && del.right == null){ if(del == root){ root = null; }else{ ancestorminu1(del); if(del == del.parent.left){ del.parent.left = null; }else{ del.parent.right = null; } del.parent = null; maintainHelp(root, what); } }else if(del.right != null && del.left == null){ //因为已经平衡,所以要删除的节点del有且仅有一个右子节点 if(root == del){ root = del.right; del.right.parent = null; del.right = null; }else{ ancestorminu1(del); if(del == del.parent.left){ del.parent.left = del.right; }else{ del.parent.right = del.right; } del.right.parent = del.parent; del.parent = del.right = null; maintainHelp(root, what); } }else if(del.left != null && del.right == null){ //因为已经平衡,所以要删除的节点del有且仅有一个左子节点 if(root == del){ root = del.left; del.left.parent = null; del.left = null; }else{ ancestorminu1(del); if(del == del.parent.left){ del.parent.left = del.left; }else{ del.parent.right = del.left; } del.left.parent = del.parent; del.parent = del.left = null; maintainHelp(root, what); } }else{ //左右子树都不为空 Node preOfDel = pre(del, data); del.data = preOfDel.data; ancestorminu1(preOfDel); preOfDel.parent.left = preOfDel.left; if(preOfDel.left != null){ preOfDel.left.parent = preOfDel.parent; } preOfDel.parent = preOfDel.left = null; maintainHelp(root, what); } }else{ return; } } /** * 在树中查找键值为data的结点 * @param data * @return */ public Node find(T data){ Node current = root; if(root == null){ return null; }else{ int result; while(current != null){ result = data.compareTo(current.data); if(result > 0){ current = current.right; }else if(result < 0){ current = current.left; }else{ return current; } } } return null; } /** * 在树中查找排名为k的节点(其实为了更好地操作,我觉得可以在每个节点中存放两个域 * lsize和rsize,分别存放该节点的左子树节点数量和右子树节点数量,但更耗内存) * @param node * @param k * @return */ public Node select(Node node, int k){ if(root == null){ try { throw new Exception("该树为空"); } catch (Exception e) { e.printStackTrace(); } }else if(root.size < k){ try { throw new Exception("该节点不存在一个排名为"+k+"的节点,但存在一个最大排名为"+root.size+"的节点"); } catch (Exception e) { e.printStackTrace(); } }else{ if(node != null){ int result; if(node.left != null){ result = node.left.size + 1; if(result == k){ return node; }else if(result < k){ return select(node.right, k - result); }else{ return select(node.left, k); } }else if(node.right != null){ if(k == 1){ return node; }else{ return select(node.right, k - 1); } }else{ return node; } } } return null; } //最大值 public T minData(){ return select(root, 1).data; } //最小值 public T maxData(){ return select(root, this.root().size).data; } //这里考虑到了要查看排名的数据元素不在树中 public int rank(Node node, T data){ Node p = find(data); T m = minData(); return data.compareTo(m) < 0 ? 1 : (p == null ? cRank(node, data) + 1 : cRank(node, data)); } //返回以node为根的树中元素值为data的排名 private int cRank(Node node, T data){ if(node != null){ int result = data.compareTo(node.data); if(node.left != null && node.right != null){ if(result < 0){ return cRank(node.left, data); }else if(result > 0){ return cRank(node.left, data) + cRank(node.right, data) + 1; } return node.left.size + 1; }else if(node.right != null && node.left == null){ if(result < 0){ return 0; }else if(result > 0){ return cRank(node.right, data) + 1; } return 1; }else if(node.left != null && node.right == null){ if(result < 0){ return cRank(node.left, data); }else if(result > 0){ return cRank(node.left, data) + 1; } return cRank(node.left, data) + 1; }else{ if(result < 0){ return 0; }else if(result > 0){ return 1; } return 1; } } return 0; } //以node节点为根某数据元素的前驱 public Node pre(Node node, T data){ Node current = node; Node preNode = null; int result; while(current != null){ result = data.compareTo(current.data); /*if(result == 0){ return current; }else*/ if(result > 0){ preNode = current; current = current.right; }else{ current = current.left; } } return preNode; } //以node节点为根某数据元素的后继 public Node succ(Node node, T data){ Node current = node; Node preNode = null; int result; while(current != null){ result = data.compareTo(current.data); /*if(result == 0){ return current; }else */if(result < 0){ preNode = current; current = current.left; }else{ current = current.right; } } return preNode; } /** * 右旋(x/y才是关键) * @param x * │ │ * x y * ││ -> ││ * y──┘└─γ α──┘└─x * ││ ││ * α─┘└─β β─┘└─γ * */ private void right_rot(Node x){ Node y = x.left; y.parent = x.parent; if(x.parent != null){ if(x == x.parent.left){ x.parent.left = y; }else{ x.parent.right = y; } } x.left = y.right; if(y.right != f88e null){ y.right.parent = x; } y.right = x; x.parent = y; y.size = x.size; x.size = (y.left == null ? y.size - 0 - 1 : y.size - y.left.size - 1); if(root == x){ root = y; } } /** * 左旋(x/y才是关键) * @param x * │ │ * x y * ││ -> ││ * α──┘└─y x──┘└─γ * ││ ││ * β─┘└─γ α─┘└─β */ private void left_rot(Node x){ Node y = x.right; y.parent = x.parent; if(x.parent != null){ if(x == x.parent.left){ x.parent.left = y; }else{ x.parent.right = y; } } x.right = y.left; if(y.left != null){ y.left.parent = x; } y.left = x; x.parent = y; y.size = x.size; x.size = (y.right == null ? y.size - 0 - 1 : y.size - y.right.size - 1); if(root == x){ root = y; } } //广度优先遍历 public List<Node> breadthFirstSearch(){ return cBreadthFirstSearch(root); } private List<Node> cBreadthFirstSearch(Node node) { List<Node> nodes = new ArrayList<Node>(); Deque<Node> deque = new ArrayDeque<Node>(); if(node != null){ deque.offer(node); } while(!deque.isEmpty()){ Node tmp = deque.poll(); nodes.add(tmp); if(tmp.left != null){ deque.offer(tmp.left); } if(tmp.right != null){ deque.offer(tmp.right); } } return nodes; } public static void main(String[] args) { SizeBalancedTree<Integer> tree = new SizeBalancedTree<Integer>(); tree.insert(30); tree.insert(20); System.out.println( tree.select(tree.root(), 1) ); tree.insert(40); tree.insert(10); tree.insert(26); tree.insert(35); tree.insert(45); tree.insert(8); tree.insert(15); tree.insert(23); tree.insert(32); tree.insert(27); tree.insert(37); tree.insert(21); tree.insert(24); System.out.println( tree.breadthFirstSearch()); tree.insert(29); System.out.println( tree.breadthFirstSearch()); System.out.println( "树中排名第14的元素为:"+tree.select(tree.root(), 14) ); System.out.println(); System.out.println( "37的排名为:"+tree.rank(tree.root(),37)); System.out.println(); System.out.println( "37的前驱为:"+tree.pre(tree.root(), 37)); System.out.println( "36的后继为:"+tree.succ(tree.root(), 36)); tree.remove(tree.root(), 26); System.out.println( tree.breadthFirstSearch()); } }
测试结果为:
[data=20,size=1] [[data=30,size=15], [data=20,size=9], [data=40,size=5], [data=10,size=3], [data=26,size=5], [data=35,size=3], [data=45,size=1], [data=8,size=1], [data=15,size=1], [data=23,size=3], [data=27,size=1], [data=32,size=1], [data=37,size=1], [data=21,size=1], [data=24,size=1]] [[data=26,size=16], [data=20,size=7], [data=35,size=8], [data=10,size=3], [data=23,size=3], [data=30,size=4], [data=40,size=3], [data=8,size=1], [data=15,size=1], [data=21,size=1], [data=24,size=1], [data=27,size=2], [data=32,size=1], [data=37,size=1], [data=45,size=1], [data=29,size=1]] 树中排名第14的元素为:[data=37,size=1] 37的排名为:14 37的前驱为:[data=35,size=8] 36的后继为:[data=37,size=1] [[data=24,size=15], [data=20,size=6], [data=35,size=8], [data=10,size=3], [data=23,size=2], [data=30,size=4], [data=40,size=3], [data=8,size=1], [data=15,size=1], [data=24,size=1], [data=27,size=2], [data=32,size=1], [data=37,size=1], [data=45,size=1], [data=29,size=1]]
另附两篇大神满的文章:
Size Balanced Tree(SBT树)整理
【平衡二叉树】SBT学习笔记
这里有C++和Python源码地址:
节点大小平衡树((Size Balanced Tree, c++和python源码)
相关文章推荐
- CQF平衡树——SBT论文——Size Balanced Tree
- 傻B树”、“Super BT” Size Balanced Tree(简称SBT)是一自平衡二叉查找树
- [转载] SBT(Size Balanced Tree)
- 初学 Size Balanced Tree(bzoj3224 tyvj1728 普通平衡树)
- Size Balanced Tree(SBT) 类模板C++实现(持续更新)
- [置顶] splay、treap、SBT(Size Balanced Tree)那点奇诡的东东(填坑ing)
- SBT(Size balanced tree)
- Size Balanced Tree(SBT)平衡二叉树
- 子树大小平衡树(SizeBalancedTree,SBT)——模板
- SBT(Size Balanced Tree)2016.9.6
- SBT模版(Size Balanced Tree)
- Size Balanced Tree(SBT)
- POJ 2761 SBT(size balanced tree)
- Size Balanced Tree(SBT) 类模板C++实现(持续更新)
- 数据结构-SBT(Size Balanced Tree)
- Size Balanced Tree(SBT) 模板
- Size Balanced Tree(SBT)平衡二叉树
- Size Balanced Tree Sbt模板
- SBT(size balanced tree) 和AVL 合二为一
- Size Balanced Tree模板