zoukankan      html  css  js  c++  java
  • 平衡二叉查找树

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


  • 相关阅读:
    前端试题-正则中test, exec, match的区别
    前端试题-什么是css sprite?优缺点?
    有哪些软件堪称「神器」,却不被大众所知?(转)
    gif,png,jpg的区别
    前端试题-两列等高布局
    20160109小问题
    动画效果之运动
    用JS控制下拉菜单效果
    获取当前时间getDate()注意点
    全心加入web前端开发,向上吧!
  • 原文地址:https://www.cnblogs.com/yfceshi/p/6907901.html
Copyright © 2011-2022 走看看