现在的位置: 首页 > 综合 > 正文

AVLTree 二叉平衡树 实现

2013年10月31日 ⁄ 综合 ⁄ 共 6026字 ⁄ 字号 评论关闭
package changsheng.datastructure;


// ******************PUBLIC OPERATIONS*********************
// void insert( x )       --> Insert x
// void remove( x )       --> Remove x (unimplemented)
// Comparable find( x )   --> Return item that matches x
// Comparable findMin( )  --> Return smallest item
// Comparable findMax( )  --> Return largest item
// boolean isEmpty( )     --> Return true if empty; else false
// void makeEmpty( )      --> Remove all items
// void printTree( )      --> Print tree in sorted order

/**
 * Implements an AVL tree. Note that all "matching" is based on the compareTo
 * method.
 */
public class AVLTree<E extends Comparable<? super E>> {
	/**
	 * Construct the tree.
	 */
	public AVLTree() {
		root = null;
	}

	/**
	 * Insert into the tree; duplicates are ignored.
	 * 
	 * @param x
	 *            the item to insert.
	 */
	public void insert(E x) {
		root = insert(x, root);
	}

	/**
	 * Remove from the tree. Nothing is done if x is not found.
	 * 
	 * @param x
	 *            the item to remove.
	 */
	public void remove(E x) {
		System.out.println("Sorry, remove unimplemented");
	}

	/**
	 * Find the smallest item in the tree.
	 * 
	 * @return smallest item or null if empty.
	 */
	public E findMin() {
		return elementAt(findMin(root));
	}

	/**
	 * Find the largest item in the tree.
	 * 
	 * @return the largest item of null if empty.
	 */
	public E findMax() {
		return elementAt(findMax(root));
	}

	/**
	 * Find an item in the tree.
	 * 
	 * @param x
	 *            the item to search for.
	 * @return the matching item or null if not found.
	 */
	public E find(E x) {
		return elementAt(find(x, root));
	}

	/**
	 * Make the tree logically empty.
	 */
	public void makeEmpty() {
		root = null;
	}

	/**
	 * Test if the tree is logically empty.
	 * 
	 * @return true if empty, false otherwise.
	 */
	public boolean isEmpty() {
		return root == null;
	}

	/**
	 * Print the tree contents in sorted order.
	 */
	public void printTree() {
		if (isEmpty())
			System.out.println("Empty tree");
		else
			printTree(root);
	}

	/**
	 * Internal method to get element field.
	 * 
	 * @param t
	 *            the node.
	 * @return the element field or null if t is null.
	 */
	private E elementAt(AVLNode<E> t) {
		return t == null ? null : t.element;
	}

	/**
	 * Internal method to insert into a subtree.
	 * 
	 * @param x
	 *            the item to insert.
	 * @param t
	 *            the node that roots the tree.
	 * @return the new root.
	 */
	private AVLNode<E> insert(E x, AVLNode<E> t) {
		if (t == null)
			t = new AVLNode<E>(x, null, null);

		else if (x.compareTo(t.element) < 0) { // 插入到左子树

			t.left = insert(x, t.left);
			/* 插入完成后检测是否平衡 */
			if (height(t.left) - height(t.right) == 2) {/*左右子树不平衡*/
				
				if (x.compareTo(t.left.element) < 0)
					t = rotateWithLeftChild(t);/*左左情况 -- 单旋转*/
				else
					t = doubleWithLeftChild(t);/*左右情况 -- 双旋转*/
			}

		} else if (x.compareTo(t.element) > 0) { // 插入到右子树

			t.right = insert(x, t.right);
			/* 插入完成后检测是否平衡 */
			if (height(t.right) - height(t.left) == 2) {/*左右子树不平衡*/
				
				if (x.compareTo(t.right.element) > 0)
					t = rotateWithRightChild(t);/*右右情况 -- 单旋转*/
				else
					t = doubleWithRightChild(t);/*右左情况 -- 双旋转*/
			}

		} else
			; // Duplicate; do nothing
		t.height = max(height(t.left), height(t.right)) + 1;
		return t;
	}

	/**
	 * Internal method to find the smallest item in a subtree.
	 * 
	 * @param t
	 *            the node that roots the tree.
	 * @return node containing the smallest item.
	 */
	private AVLNode<E> findMin(AVLNode<E> t) {
		if (t == null)
			return t;

		while (t.left != null)
			t = t.left;
		return t;
	}

	/**
	 * Internal method to find the largest item in a subtree.
	 * 
	 * @param t
	 *            the node that roots the tree.
	 * @return node containing the largest item.
	 */
	private AVLNode<E> findMax(AVLNode<E> t) {
		if (t == null)
			return t;

		while (t.right != null)
			t = t.right;
		return t;
	}

	/**
	 * Internal method to find an item in a subtree.
	 * 
	 * @param x
	 *            is item to search for.
	 * @param t
	 *            the node that roots the tree.
	 * @return node containing the matched item.
	 */
	private AVLNode<E> find(E x, AVLNode<E> t) {
		while (t != null)
			if (x.compareTo(t.element) < 0)
				t = t.left;
			else if (x.compareTo(t.element) > 0)
				t = t.right;
			else
				return t; // Match

		return null; // No match
	}

	/**
	 * Internal method to print a subtree in sorted order.
	 * 
	 * @param t
	 *            the node that roots the tree.
	 */
	private void printTree(AVLNode<E> t) {
		if (t != null) {
			printTree(t.left);
			System.out.println(t.element);
			printTree(t.right);
		}
	}

	/**
	 * Return the height of node t, or -1, if null.
	 */
	private static <E extends Comparable<? super E>> int height(AVLNode<E> t) {
		return t == null ? -1 : t.height;
	}

	/**
	 * Return maximum of lhs and rhs.
	 */
	private static int max(int lhs, int rhs) {
		return lhs > rhs ? lhs : rhs;
	}

	/**
	 * Rotate binary tree node with left child. For AVL trees, this is a single
	 * rotation for case 1. Update heights, then return new root.
	 */
	private static <E extends Comparable<? super E>> AVLNode<E> rotateWithLeftChild(
			AVLNode<E> k2) {
		AVLNode<E> k1 = k2.left;
		k2.left = k1.right;
		k1.right = k2;
		k2.height = max(height(k2.left), height(k2.right)) + 1;
		k1.height = max(height(k1.left), k2.height) + 1;
		return k1;
	}

	/**
	 * Rotate binary tree node with right child. For AVL trees, this is a single
	 * rotation for case 4. Update heights, then return new root.
	 */
	private static <E extends Comparable<? super E>> AVLNode<E> rotateWithRightChild(
			AVLNode<E> k1) {
		AVLNode<E> k2 = k1.right;
		k1.right = k2.left;
		k2.left = k1;
		k1.height = max(height(k1.left), height(k1.right)) + 1;
		k2.height = max(height(k2.right), k1.height) + 1;
		return k2;
	}

	/**
	 * Double rotate binary tree node: first left child with its right child;
	 * then node k3 with new left child. For AVL trees, this is a double
	 * rotation for case 2. Update heights, then return new root.
	 */
	private static <E extends Comparable<? super E>> AVLNode<E> doubleWithLeftChild(
			AVLNode<E> k3) {
		k3.left = rotateWithRightChild(k3.left);
		return rotateWithLeftChild(k3);
	}

	/**
	 * Double rotate binary tree node: first right child with its left child;
	 * then node k1 with new right child. For AVL trees, this is a double
	 * rotation for case 3. Update heights, then return new root.
	 */
	private static <E extends Comparable<? super E>> AVLNode<E> doubleWithRightChild(
			AVLNode<E> k1) {
		k1.right = rotateWithLeftChild(k1.right);
		return rotateWithRightChild(k1);
	}

	/** The tree root. */
	private AVLNode<E> root;

	// Test program
	@SuppressWarnings("unused")
	public static void main(String[] args) {
		AVLTree<Integer> t = new AVLTree<Integer>();
		final int NUMS = 4000;
		final int GAP = 37;

		System.out.println("Checking... (no more output means success)");

		for (int i = GAP; i != 0; i = (i + GAP) % NUMS)
			t.insert(new Integer(i));

		if (NUMS < 40)
			t.printTree();
		if (((Integer) (t.findMin())).intValue() != 1
				|| ((Integer) (t.findMax())).intValue() != NUMS - 1)
			System.out.println("FindMin or FindMax error!");

		for (int i = 1; i < NUMS; i++)
			if (((Integer) (t.find(new Integer(i)))).intValue() != i)
				System.out.println("Find error1!");
	}
}

package changsheng.datastructure;

// Basic node stored in AVL trees
// Note that this class is not accessible outside
// of package DataStructures

class AVLNode<E extends Comparable< ? super E>> {
	// Constructors
	AVLNode(E theElement) {
		this(theElement, null, null);
	}

	AVLNode(E theElement, AVLNode<E> lt, AVLNode<E> rt) {
		element = theElement;
		left = lt;
		right = rt;
		height = 0;
	}

	// Friendly data; accessible by other package routines
	E element; // The data in the node
	AVLNode<E> left; // Left child
	AVLNode<E> right; // Right child
	int height; // Height
}

抱歉!评论已关闭.