AVL 树的插入与旋转

补存一些参考文档

二叉平衡树的旋转操作_取酌由君的博客-CSDN博客_平衡树旋转旋转是很多二叉平衡树维持平衡的主要手段,在这里复习一下。其实旋转过程中节点位置的变化只要遵循一个原则就行了:比Root小的在左子树,比Root大的在右子树。(当然这里前提条件是左小右大)。情况一:插入F节点导致失衡:这里失衡的是A的左右子树,很容易就可以想到旋转B-A链,值得注意的是E节点,它原先在B的右子树,现在也依然在B的右子树,它原先在A的左子树,现在也依然在A的左子树。若插...https://blog.csdn.net/saasanken/article/details/80796178 

平衡二叉树的旋转以及简便方法_不要清汤锅的博客-CSDN博客_平衡二叉树的旋转刚开始听这个平衡二叉树的旋转,一听就蒙了,后来看了很多视频,有很多的说法。下面来介绍平衡二叉树平衡二叉树:就是每个节点的平衡因子(Balance Factor)(以下简称BF)的绝对值小于等于1,即为0或1。而BF就是每个节点左子树的高度减去右子树的高度。平衡二叉树的旋转共有四种情况:下面说一个定义,新插入的节点为破坏点,而由于破坏点的存在使二叉树失衡(|BF|>1)的节点为被破坏节点    1.LL型:即为被破坏节点的左子树的左子树插入破坏节点。如图:数值为...https://blog.csdn.net/hello_program_world/article/details/115472968 

/** * * @author xuejianxinokok * @date 2011-05-28 * */
public class AVLTree {
	/**
	 * * p (parent) * lc (left child) * rc (right child) * lgc (left grandchild) *
	 * rgc (right grandchild)
	 */
	private static class AVLNode {
		public Object nodeValue;
		public AVLNode left, right;
		public int height;

		public AVLNode(Object item) {
			nodeValue = item;
			left = null;
			right = null;
			height = 0;
		}
	}

	private AVLNode root;// 树根
	private int treeSize;// 树节点数量

	public AVLTree() { // 空构造函数
		root = null;
		treeSize = 0;
	}

	public AVLTree(AVLNode item) {
		root = item;
		treeSize = 1;
	}

	public boolean add(Object item) {
		try {
			root = addNode(root, item);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		treeSize++;
		return true;
	}

	private AVLNode addNode(AVLNode t, Object item) {
		if (null == t) {
			t = new AVLNode(item);
		} else if (((Comparable) item).compareTo((Comparable) t.nodeValue) < 0) {
			// 左子树
			t.left = addNode(t.left, item);
			if (height(t.left) - height(t.right) == 2) {
				if (((Comparable) item).compareTo((Comparable) t.left.nodeValue) < 0) {
					t = singleRotateRight(t);// 左子树 左节点
				} else {
					t = doubleRotateRight(t);// 左子树 右节点
				}
			}
		} else if (((Comparable) item).compareTo((Comparable) t.nodeValue) > 0) { // 右子树
			t.right = addNode(t.right, item);
			if (height(t.left) - height(t.right) == -2) {
				if (((Comparable) item).compareTo((Comparable) t.right.nodeValue) > 0) {
					t = singleRotateLeft(t);
				} else {
					t = doubleRotateLeft(t);
				}
			}
		}
		t.height = max(height(t.left), height(t.right)) + 1;
		return t;
	}

	/**
	 * 以 p 节点的左子节点 右旋转 * p lc * / / / / * lc rc ===> lgc p * / / / / / * lgc rgc
	 * item rgc rc * / item * * @param p * @return
	 */
	private AVLNode singleRotateRight(AVLNode p) {
		AVLNode lc = p.left;// 定位到 父节点P 的 左子节点 p.left=lc.right; lc.right=p;
		p.height = max(height(p.left), height(p.right)) + 1;
		lc.height = max(height(lc.left), height(lc.right)) + 1;
		return lc;
	}

	/**
	 * 以 p 节点的右子节点 左旋转 * p rc * / / / / * lc rc ===> p rgc * / / / / / * lgc rgc lc
	 * lgc item * / * item * @param p * @return
	 */
	private AVLNode singleRotateLeft(AVLNode p) {
		AVLNode rc = p.right;// 定位到 父节点P 的 左子节点
		p.right = rc.left;
		rc.left = p;
		p.height = max(height(p.left), height(p.right)) + 1;
		rc.height = max(height(rc.left), height(rc.right)) + 1;
		return rc;
	}

	/**
	 * * p p rgc / / / / / / * lc rc 以rgc 左旋 rgc rc 以rgc右旋 lc p * / / ==========> /
	 * / ===========> / / / / * lgc rgc lc item lgc 空 item rc * / / / / * 空 item lgc
	 * 空 * @param p * @return
	 */
	private AVLNode doubleRotateRight(AVLNode p) {
		p.left = singleRotateLeft(p.left);
		return singleRotateRight(p);
	}

	/**
	 * * p p lgc / / / / / / * lc rc lgc右旋 lc lgc lgc左旋 p rc * / / ===========> / /
	 * ==========> / / / / * lgc rgc item rc lc item 空 rgc * / / / / * item 空 空 rgc
	 * * @param p * @return
	 */
	private AVLNode doubleRotateLeft(AVLNode p) {
		p.right = singleRotateRight(p.right);
		return singleRotateLeft(p);
	}

	private int max(int height1, int height2) {
		if (height1 >= height2) {
			return height1;
		} else {
			return height2;
		}
	}

	private static int height(AVLNode t) {
		if (null == t) {
			return -1;
		} else {
			return t.height;
		}
	}

	public static void main(String[] args) {
		AVLTree tree = new AVLTree();
		tree.add("1");
		tree.add("2");
		tree.add("3");
		tree.add("4");
		tree.add("5");
		/*
		 * tree.add("3"); tree.add("2"); tree.add("1");
		 */ System.out.println("");
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值