AVL树 发表于 2018-08-21 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278class AVLTree<K extends Comparable<K>, V> { private class Node { public K key; public V value; public Node left, right; public int height; public Node(K key, V value) { this.key = key; this.value = value; left = null; right = null; height = 1; } } private Node root; private int size; public AVLTree() { root = null; size = 0; } public int getSize() { return size; } // 获得节点的高度 private int getHeight(Node node) { if (node == null) { return 0; } return node.height; } public boolean isEmpty() { return size == 0; } public boolean contains(K key) { return getNode(root, key) != null; } // 添加元素 public void add(K key, V value) { root = add(root, key, value); } // 向以node为根的二分搜索树种插入元素E private Node add(Node node, K key, V value) { // 当我们递归到null的时候就一定要创建一个节点 if (node == null) { size++; return new Node(key, value); } if (key.compareTo(node.key) < 0) { node.left = add(node.left, key, value); } else if (key.compareTo(node.key) > 0) { node.right = add(node.right, key, value); } else { node.value = value; } // 更新height node.height = 1 + Math.max(getHeight(node.left), getHeight(node.right)); // 计算平衡因子 int balanceFactor = getBalanceFactor(node); // 平衡维护,插入的元素在不平衡的节点的左侧的左侧 LL if (balanceFactor > 1 && getBalanceFactor(node.left) >= 0) { return rightRotate(node); } // 平衡维护,插入的元素在不平衡的节点的右侧的右侧 RR if (balanceFactor < -1 && getBalanceFactor(node.right) <= 0) { return leftRotate(node); } // 平衡维护,插入的元素在不平衡的节点的左侧的右侧 LR if (balanceFactor > 1 && getBalanceFactor(node.left) < 0) { node.left = leftRotate(node.left); return rightRotate(node); } // 平衡维护,插入的元素在不平衡的节点的右侧的左侧 RL if (balanceFactor < -1 && getBalanceFactor(node.right) > 0) { node.right = rightRotate(node.right); return leftRotate(node); } return node; } private Node rightRotate(Node y) { Node x = y.left; Node T3 = x.right; x.right = y; y.left = T3; // 更新height y.height = Math.max(getHeight(y.left), getHeight(y.right)) + 1; x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1; return x; } private Node leftRotate(Node y) { Node x = y.right; Node T2 = x.left; x.left = y; y.right = T2; y.height = Math.max(getHeight(y.left), getHeight(y.right)) + 1; x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1; return x; } private int getBalanceFactor(Node node) { if (node == null) { return 0; } return getHeight(node.left) - getHeight(node.right); } // 判断该二叉树是不是一颗平衡搜索树 public boolean isBST() { ArrayList<K> keys = new ArrayList<>(); inOrder(root, keys); for (int i = 1; i < keys.size(); i++) { if (keys.get(i - 1).compareTo(keys.get(i)) > 0) { return false; } } return true; } // 判断以Node为节点的二叉树是不是一颗平衡二叉树 public boolean isBalanced() { return isBalanced(root); } private boolean isBalanced(Node node) { if (node == null) { return true; } int balanceFactor = getBalanceFactor(node); if (balanceFactor > 1) { return false; } return isBalanced(node.left) && isBalanced(node.right); } private void inOrder(Node node, ArrayList<K> keys) { if (node == null) { return; } inOrder(node.left, keys); keys.add(node.key); inOrder(node.right, keys); } private Node getNode(Node node, K key) { if (node == null) { return null; } if (key.compareTo(node.key) < 0) { return getNode(node.left, key); } else if (key.compareTo(node.key) > 0) { return getNode(node.right, key); } else { return node; } } public V get(K key) { Node node = getNode(root, key); return node == null ? null : node.value; } public void set(K key, V value) { Node node = getNode(root, key); if (node == null) { throw new IllegalArgumentException(key + "doesn't exist !"); } node.value = value; } public V remove(K key) { Node node = getNode(root, key); if (node != null) { root = remove(root, key); return node.value; } return null; } private Node remove(Node node, K key) { if (node == null) { return null; } Node retNode; if (key.compareTo(node.key) < 0) { node.left = remove(node.left, key); retNode = node; } else if (key.compareTo(node.key) > 0) { node.right = remove(node.right, key); retNode = node; } else { // 3种情况 // 待删除节点左子树为空 if (node.left == null) { Node rightNode = node.right; node.right = null; size--; retNode = rightNode; } else if (node.right == null) { // 待删除节点右子树为空 Node leftNode = node.left; node.left = null; size--; retNode = leftNode; } else { // 待删除节点左右子树均不为空的情况 // 找到比待删除节点大的最小节点,即待删除节点右子树的最小节点。 // 用这个节点顶替待删除节点的位置 Node successor = minimum(node.right); // 这里我们进行了删除size进行了减操作 successor.right = remove(node.right, successor.key); successor.left = node.left; node.left = node.right = null; retNode = successor; } } if (retNode == null) { return null; } // 更新height retNode.height = 1 + Math.max(getHeight(retNode.left), getHeight(retNode.right)); // 计算平衡因子 int balanceFactor = getBalanceFactor(retNode); // 平衡维护,插入的元素在不平衡的节点的左侧的左侧 LL if (balanceFactor > 1 && getBalanceFactor(retNode.left) >= 0) { return rightRotate(retNode); } // 平衡维护,插入的元素在不平衡的节点的右侧的右侧 RR if (balanceFactor < -1 && getBalanceFactor(retNode.right) <= 0) { return leftRotate(retNode); } // 平衡维护,插入的元素在不平衡的节点的左侧的右侧 LR if (balanceFactor > 1 && getBalanceFactor(retNode.left) < 0) { retNode.left = leftRotate(retNode.left); return rightRotate(retNode); } // 平衡维护,插入的元素在不平衡的节点的右侧的左侧 RL if (balanceFactor < -1 && getBalanceFactor(retNode.right) > 0) { retNode.right = rightRotate(retNode.right); return leftRotate(retNode); } return retNode; } // 最小值 public V minimum() { if (size == 0) { throw new IllegalArgumentException("BST is empty"); } return minimum(root).value; } // 返回已node为根的二分搜索树的最小值所在的节点 private Node minimum(Node node) { if (node.left == null) { return node; } return minimum(node.left); }} -------------本文结束感谢您的阅读-------------