码迷,mamicode.com
首页 > 其他好文 > 详细

AVL树

时间:2014-08-10 15:47:10      阅读:312      评论:0      收藏:0      [点我收藏+]

标签:java   io   for   art   ar   new   ad   ef   

public class AVLTree {
	public static class AVLTreeNode {
		AVLTreeNode mLeftNode;
		AVLTreeNode mRightNode;
		AVLTreeNode mParent;
		public int mHeight;

		int mValue;
		
		public AVLTreeNode() {
			mLeftNode = null;
			mRightNode = null;
			mParent = null;
			mHeight = 0;
		}
		
		public AVLTreeNode(int value) {
			this();
			mValue = value;
		}
	}
	
	public static int getNodeHeight(AVLTreeNode node) {
		return node == null ? -1 : node.mHeight;
	}
	
	private AVLTreeNode mHeader;
	
	public AVLTreeNode find(int value) {
		AVLTreeNode node = mHeader;
		return findNode(node, value);
	}
	
	private AVLTreeNode findNode(AVLTreeNode startNode, int value) {
		AVLTreeNode node = startNode;
		while (null != node) {
			if (node.mValue == value) {
				return node;
			} else if (value > node.mValue) {
				node = node.mRightNode;
			} else {
				node = node.mLeftNode;
			}
		}
		return null;
	}
	
	public void printLevel() {
		System.out.println("=======================================");
		printLevelNode(mHeader, 0);
		System.out.println("=======================================");
	}
	
	private void printLevelNode(AVLTreeNode node, int level) {
		if (null != node) {
			for (int i = 0; i < level; i++) {
				System.out.print("    ");
			}
			System.out.println(String.valueOf(node.mValue));
			printLevelNode(node.mLeftNode, level + 1);
			printLevelNode(node.mRightNode, level + 1);
		}
	}
	
	public void print() {
		printNode(mHeader);
	}
	
	private void printNode(AVLTreeNode node) {
		if (null != node) {
			printNode(node.mLeftNode);
			System.out.print("     " + node.mValue);
			printNode(node.mRightNode);
		}
	}
	
	public int findMin() {
		if (null == mHeader) {
			throw new IllegalStateException("树为空");
		}
		
		AVLTreeNode node = findMinNode(mHeader);
		return node.mValue;
	}
	
	private AVLTreeNode findMinNode(AVLTreeNode startNode) {
		AVLTreeNode node = startNode;
		while (null != node.mLeftNode) 
			node = node.mLeftNode;
		return node;
	}
	
	public int findMax() {
		if (null == mHeader) {
			throw new IllegalStateException("树为空");
		}
		
		AVLTreeNode node = findMaxNode(mHeader);
		return node.mValue;
	}
	
	private AVLTreeNode findMaxNode(AVLTreeNode startNode) {
		AVLTreeNode node = startNode;
		while (null != node.mRightNode) 
			node = node.mRightNode;
		return node;
	}
	
	// 插入:
	public void insert(int value) {
		insert(mHeader, mHeader, value);
	}
	
	private void insert(AVLTreeNode targetParent, AVLTreeNode target, int value) {
		if (target == null) { // 当前节点已经是空节点了,也就是必须在这里插入了
			target = new AVLTreeNode();
			target.mValue = value;
			if (null == targetParent) {	// 这才说明是空树
				mHeader = target;
			} else {
				target.mParent = targetParent;
				if (targetParent.mValue > value) {
					targetParent.mLeftNode = target;
				} else {
					targetParent.mRightNode = target;
				}
			}
			return;
		} else if (target.mValue > value) {	// 递归插入:在左边插入,只会改变左子树的高度
			insert(target, target.mLeftNode, value);
			// 向左侧插入,只能左侧比右侧大
			if (getNodeHeight(target.mLeftNode) - getNodeHeight(target.mRightNode) >= 2) {
				if (target.mLeftNode.mValue > value) { // LL
					rightRotate(target);
				} else {								// LR
					leftRightRotate(target);
				}
			}
		} else if (target.mValue < value) {
			insert(target, target.mRightNode, value);
			if (getNodeHeight(target.mRightNode) - getNodeHeight(target.mLeftNode) >= 2) {
				if (target.mRightNode.mValue < value) {  // RR
					leftRotate(target);
				} else {									// RL
					rightLeftRotate(target);
				}
			}
		} else { // 已经存在了
			return;
		}
		
		// 重新计算高度:
		int leftHeight = getNodeHeight(target.mLeftNode);
		int rightHeight = getNodeHeight(target.mRightNode);
		target.mHeight = Math.max(leftHeight, rightHeight) + 1;
	}
	
	public void deleteNode(int value) {
		AVLTreeNode delNode = findNode(mHeader, value);
		if (null != delNode) {
			deleteNode(mHeader, value);
		} else {
			System.out.println("can not find node");
		}
	}
	
	public void deleteNode(AVLTreeNode target, int value) {
		if (target.mValue > value) {
			deleteNode(target.mLeftNode, value);
		} else if (target.mValue < value) {
			deleteNode(target.mRightNode, value);
		} else if (null != target.mLeftNode) {		// 就是本尊:从左边替换
			// 替换
			target.mValue = findMaxNode(target.mLeftNode).mValue;
			deleteNode(target.mLeftNode, target.mValue);
		} else if (null != target.mRightNode) {		// 就是本尊:从右边替换
			target.mValue = findMinNode(target.mRightNode).mValue;
			deleteNode(target.mRightNode, target.mValue);
		} else {									// 没有孩子:直接删除
			if (target.mParent.mLeftNode == target) { // 做孩子
				target.mParent.mLeftNode = null;
			} else {
				target.mParent.mRightNode = null;
			}
			return;
		}
		
		int leftHeight = getNodeHeight(target.mLeftNode);
		int rightHeight = getNodeHeight(target.mRightNode);
		target.mHeight = Math.max(leftHeight, rightHeight) + 1;
		if (rightHeight - leftHeight >= 2) {
			if (target.mRightNode.mRightNode == null) {
				rightLeftRotate(target);
			} else {
				leftRotate(target);
			}
		} else if (leftHeight - rightHeight >= 2) {
			if (null == target.mLeftNode.mLeftNode) {
				leftRightRotate(target);
			} else {
				rightRotate(target);
			}
		}
	}
	
	/**
	 * 左旋转
	 * @param target 目标
	 */
	private void leftRotate(AVLTreeNode target) {
		AVLTreeNode rightChild = target.mRightNode;
		// 处理右子树的左节点
		target.mRightNode = rightChild.mLeftNode;
		if (null != rightChild.mLeftNode) {
			rightChild.mLeftNode.mParent = target;
		}
		
		// 处理父节点
		if (target.mParent == null) { // 没有父节点
			mHeader = rightChild;
			rightChild.mParent = null;
		} else if (target.mParent.mLeftNode == target) { // 该子树在父节点的左子树上
			target.mParent.mLeftNode = rightChild;
			rightChild.mParent = target.mParent;
		} else {										 // 该子树在父节点的右子树上
			target.mParent.mRightNode = rightChild;
			rightChild.mParent = target.mParent;
		}
		
		// 颠倒父子关系
		rightChild.mLeftNode = target;
		target.mParent = rightChild;
		
		// 计算高度:
		int leftHeight = getNodeHeight(target.mLeftNode);
		int rightHeight = getNodeHeight(target.mRightNode);
		target.mHeight = Math.max(leftHeight, rightHeight) + 1;
		
		// rightChild已经是父节点了
		leftHeight = getNodeHeight(rightChild.mLeftNode);
		rightHeight = getNodeHeight(rightChild.mRightNode);
		rightChild.mHeight = Math.max(leftHeight, rightHeight) + 1;
	}
	
	private void rightRotate(AVLTreeNode target) {
		AVLTreeNode leftChild = target.mLeftNode;
		// 处理左子树的右节点
		target.mLeftNode = leftChild.mRightNode;
		if (null != leftChild.mRightNode) {
			leftChild.mRightNode.mParent = target;
		}
		
		// 处理父节点:
		if (null == target.mParent) {		// 本身就是根
			mHeader = leftChild;
			leftChild.mParent = null;
		} else if (target.mParent.mLeftNode == target) {
			target.mParent.mLeftNode = leftChild;
			leftChild.mParent = target.mParent;
		} else {
			target.mParent.mRightNode = leftChild;
			leftChild.mParent = target.mParent;
		}
		
		// 颠倒父子关系:
		leftChild.mRightNode = target;
		target.mParent = leftChild;
		
		// 计算target的高度
		int leftHeight = getNodeHeight(target.mLeftNode);
		int rightHeight = getNodeHeight(target.mRightNode);
		target.mHeight = Math.max(leftHeight, rightHeight) + 1;
		
		// 计算leftChild(现在的父节点)
		leftHeight = getNodeHeight(leftChild.mLeftNode);
		rightHeight = getNodeHeight(leftChild.mRightNode);
		leftChild.mHeight = Math.max(leftHeight, rightHeight) + 1;
	}
	
	private void leftRightRotate(AVLTreeNode target) {
		leftRotate(target.mLeftNode);
		rightRotate(target);
	}
	
	private void rightLeftRotate(AVLTreeNode target) {
		rightRotate(target.mRightNode);
		leftRotate(target);
	}
	
	public static void main(String[] args) {
		AVLTree tree = new AVLTree();
		Random r = new Random(10);
		int length = 10;
		int value = 0;
		for (int i = 0; i < length; i++) {
			value = r.nextInt(1000);
			tree.insert(value);
		}
		tree.print();
		
		AVLTreeNode node = tree.find(value);
		if (null != node) {
			System.out.println("\nFind Value: " + node.mValue);
			// 把value到跟依次打印出来:
			System.out.println("从node到根的路径:");
			while (node != null) {
				System.out.print("     " + node.mValue);
				node = node.mParent;
			}
		} else {
			System.out.println("\nCANNOT Find Value: " + value);
		}
		
		int maxValue = tree.findMax();
		int minValue = tree.findMin();
		System.out.println("\n最大值:" + maxValue + ", 最小值:" + minValue);
		
		tree.printLevel();
		tree.deleteNode(293);
		tree.printLevel();
	}
}

AVL树,布布扣,bubuko.com

AVL树

标签:java   io   for   art   ar   new   ad   ef   

原文地址:http://blog.csdn.net/buleriver/article/details/38469959

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!