标签:左右子树 调整 选择 ring content pack .com abs 二叉查找树
package avitree; /** * 平衡二叉查找树类 * * @param <T> */ public class AvlTree<T extends Comparable<? super T>> { public static void main(String[] args) { AvlTree<Integer> tree = new AvlTree<Integer>(); //第一组数据 測试 右左双旋转 // tree.insert(9); // tree.insert(5); // tree.insert(10); // tree.insert(7); // tree.insert(6);// 插这个的时候会有双旋转哦,用于測试 右左双旋转 // tree.preOrder(tree.root); //第二组数据 測试左右双旋转 tree.insert(9); tree.insert(5); tree.insert(20); tree.insert(17); tree.insert(18); tree.preOrder(tree.root); } /** * 树的根节点 */ public AvlNode<T> root = null; /** * 构造一颗空的平衡二叉树 * */ public AvlTree() { } /** * 插入一个元素,通过这种方法来插入元素 * @param element */ public void insert(T element) { if (this.root == null) { this.root = insert(element, this.root); } else { insert(element, this.root); } } /** * 插入一个包括元素的新节点 * * @param element * @param target * @return */ private AvlNode<T> insert(T element, AvlNode<T> target) { if (target == null) { return new AvlNode<T>(element, null, null); } int compareResult = element.compareTo(target.element);// 比較里面的元素大小 if (compareResult < 0) { target.left = insert(element, target.left); if (Math.abs(height(target.left) - height(target.right)) > 1) {// 左右子树高度差>1 打破平衡。选择单旋转或者双旋转调节平衡 if (element.compareTo(target.left.element) < 0) {//单旋转 target = rotateLeft(target); } else {// 双旋转 target = doubleRotateLeft(target); } } } else if (compareResult > 0) { target.right = insert(element, target.right); if (Math.abs(height(target.left) - height(target.right)) > 1) { if (element.compareTo(target.right.element) > 0) {//单旋转 target = rotateRight(target); } else {//双旋转 target = doubleRotateRight(target); } } } else {//同样元素不予理会 } target.height = Math.max(height(target.left), height(target.right)) + 1; return target; } /** * 单旋转 左旋转 * @param target * @return */ private AvlNode<T> rotateLeft(AvlNode<T> k2) { AvlNode<T> k1 = k2.left; k2.left = k1.right; k1.right = k2; k2.height = Math.max(height(k2.left), height(k2.right)) + 1; k1.height = Math.max(height(k1.left), height(k1.right)) + 1; return k1; } private AvlNode<T> rotateRight(AvlNode<T> k2) { AvlNode<T> k1 = k2.right; k2.right = k1.left; k1.left = k2; k2.height = Math.max(height(k2.left), height(k2.right)) + 1; k1.height = Math.max(height(k1.left), height(k1.right)) + 1; return k1; } private AvlNode<T> doubleRotateLeft(AvlNode<T> k3) { k3.left = rotateRight(k3.left); return rotateLeft(k3); } private AvlNode<T> doubleRotateRight(AvlNode<T> k3) { k3.right = rotateLeft(k3.right); return rotateRight(k3); } /** * 先序遍历測试下程序有没有bug * @param node */ public void preOrder(AvlNode<T> node) { System.out.println(node.element); if (node.left != null) { preOrder(node.left); } if (node.right != null) { preOrder(node.right); } } /** * 获取某个节点的高度 * * @param node * @return */ public int height(AvlNode<T> node) { return node == null ? -1 : node.height; } /** * 节点类。採用静态内部类构造 * * @param <T> */ private static class AvlNode<T> { /** 节点存储的数据 。泛型类型。能够存储随意类型的元素 **/ private T element; /** 节点的左孩子 **/ AvlNode<T> left; /** 节点的右孩子 **/ AvlNode<T> right; /** 节点高度。节点为null时为-1, 新插入的节点为0,插入时递归调整父节点的高度 **/ private int height; public AvlNode(T element, AvlNode<T> leftChild, AvlNode<T> rightChild) { this.element = element; this.left = leftChild; this.right = rightChild; } @Override public String toString() { return "node:" + this.element + " height:" + height; } } }
标签:左右子树 调整 选择 ring content pack .com abs 二叉查找树
原文地址:http://www.cnblogs.com/yfceshi/p/6907901.html