天天看点

平衡二叉查找树

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;
    }

  }

}