其实是存一下代码
1. AVL的java实现
维护一下每个点左右子树深度差,差绝对值大于2就转,转的方式和treap, splay转的方式差不多。旋转操作可以使两端差归零变得更平衡。
虽然平衡但转的次数太多反而慢了(?),有空回来整理下,先咕着[旺柴]
1 import java.util.*; 2 class TestMain { 3 public static void main(String[] args) { 4 AvlTree mytree = new AvlTree(); 5 Scanner jdr = new Scanner(System.in); 6 int t = jdr.nextInt(); 7 while(t > 0) { 8 int opt = jdr.nextInt(), x = jdr.nextInt(); 9 switch (opt) { 10 case 1: 11 mytree.insert(x); 12 break; 13 case 2: 14 mytree.delete(x); 15 break; 16 case 3: 17 System.out.println(mytree.queryRank(x)); 18 break; 19 case 4: 20 System.out.println(mytree.numAt(x)); 21 break; 22 case 5: 23 System.out.println(mytree.queryPrev(x)); 24 break; 25 case 6: 26 System.out.println(mytree.queryPost(x)); 27 break; 28 } 29 t--; 30 } 31 jdr.close(); 32 return ; 33 } 34 } 35 36 public class AvlTree { 37 TreeNode root; 38 static TreeNode buffer; 39 AvlTree() { 40 root = null; 41 } 42 public void insert(int x) { 43 root = insert(root, null, x); 44 return ; 45 } 46 public void delete(int x) { 47 root = delete(root, null, x); 48 return ; 49 } 50 public int queryRank(int x) { 51 return queryRank(root, x); 52 } 53 public int numAt(int index) { 54 return queryVal(root, index); 55 } 56 public int queryPrev(int x) { 57 findPrev(root, x); 58 return buffer.value; 59 } 60 public int queryPost(int x) { 61 findPost(root, x); 62 return buffer.value; 63 } 64 private static TreeNode insert(TreeNode node, TreeNode fa, int x) { 65 if(node == null) return new TreeNode(x, fa); 66 if(x < node.value) node.child[0] = insert(node.child[0], node, x); 67 else if(node.value < x) node.child[1] = insert(node.child[1], node, x); 68 else node.num ++; 69 node.push_up(); 70 if(node.diff==-2 || node.diff==2) { 71 int p = (node.diff + 2) / 4, q = -node.diff/2; 72 if(node.child[p].diff == q) 73 node.child[p] = rotate(node.child[p], 1 - p); 74 node = rotate(node, p); 75 } 76 return node; 77 } 78 private static TreeNode delete(TreeNode node, TreeNode fa, int x) { 79 if(node == null) return null; 80 if(x < node.value) node.child[0] = delete(node.child[0], node, x); 81 else if(node.value < x) node.child[1] = delete(node.child[1], node, x); 82 else { 83 if(node.child[0]==null && node.child[1]==null) { 84 node.num --; 85 if(node.num == 0) return null; 86 }else { 87 int p = (node.diff > 0) ? 1 : 0; 88 node = rotate(node, p); 89 node.child[1-p] = delete(node.child[1-p], node, x); 90 } 91 } 92 node.push_up(); 93 if(node.diff==-2 || node.diff==2) { 94 int p = (node.diff + 2) / 4, q = -node.diff/2; 95 if(node.child[p].diff == q) 96 node.child[p] = rotate(node.child[p], 1 - p); 97 node = rotate(node, p); 98 } 99 return node; 100 } 101 private static TreeNode rotate(TreeNode node, int direction) { 102 int p = direction, q = 1 - direction; 103 TreeNode tmp = node.child[p]; 104 node.child[p] = tmp.child[q]; 105 tmp.child[q] = node; 106 tmp.father = node.father; 107 node.father = tmp; 108 node.push_up(); 109 tmp.push_up(); 110 return tmp; 111 } 112 private static int queryRank(TreeNode node, int x) { 113 if(node == null) return 0; 114 if(x < node.value) 115 return queryRank(node.child[0], x); 116 else if(node.value < x) 117 return queryRank(node.child[1], x) + node.num + node.childWeight(0); 118 return node.childWeight(0) + 1; 119 } 120 private static int queryVal(TreeNode node, int index) { 121 if(node == null) return 0; 122 if(node.childWeight(0) >= index) 123 return queryVal(node.child[0], index); 124 else if(node.childWeight(0) + node.num < index) 125 return queryVal(node.child[1], index - node.childWeight(0) - node.num ); 126 return node.value; 127 } 128 private static void findPrev(TreeNode node, int x) { 129 if(node == null) return ; 130 if(node.value < x) { 131 buffer = node; 132 findPrev(node.child[1], x); 133 }else findPrev(node.child[0], x); 134 return ; 135 } 136 private static void findPost(TreeNode node, int x) { 137 if(node == null) return ; 138 if(node.value > x) { 139 buffer = node; 140 findPost(node.child[0], x); 141 }else findPost(node.child[1], x); 142 return ; 143 } 144 } 145 class TreeNode { 146 int value, diff, height, num, weight; 147 TreeNode father; 148 TreeNode[] child; 149 TreeNode() {} 150 TreeNode(int x) { 151 value = x; 152 diff = 0; 153 num = 1; 154 weight = 1; 155 height = 0; 156 father = null; 157 child = new TreeNode[2]; 158 } 159 TreeNode(int x, TreeNode fa) { 160 value = x; 161 diff = 0; 162 num = 1; 163 weight = 1; 164 height = 0; 165 father = fa; 166 child = new TreeNode[2]; 167 } 168 public void push_up() { 169 int h1 = heightOf(child[1]), h0 = heightOf(child[0]); 170 height = max(h0, h1) + 1; 171 diff = h1 - h0; 172 weight = childWeight(0) + childWeight(1) + num; 173 return ; 174 } 175 public int childWeight(int i){ 176 if(child[i] != null) return child[i].weight; 177 return 0; 178 } 179 private static int heightOf(TreeNode node) { 180 if(node != null) return node.height; 181 return -1; 182 } 183 private static int max(int x, int y){ 184 if(x > y) return x; 185 return y; 186 } 187 }