数据结构-AVL自平衡树

AVL

名字缘由:G.M.Adelson-Velsky和E.M.Landis
是一种最早的自平衡二分搜索树结构

平衡二叉树

满平衡二叉树一定是平衡二叉树
完全二叉树也是平衡二叉树,叶子节点深度相差不为1
线段树也是平衡二叉树,叶子节点深度相差不为1
在这里插入图片描述

AVL平衡二叉树的定义

对于任意一个节点,左子树和右子树的高度差不能超过1
平衡二叉树的高度和节点数量之间的关系也是O(logn)的

如何调整高度

**先标记高度
计算平衡因子 节点的左右子树的高度差
**
在这里插入图片描述
在这里插入图片描述

自平衡实现

加入节点后,沿着节点向上回溯维护平衡性
右旋转LL
左旋转RR
LR
RL

  • 插入的元素在不平衡节点的左侧的左侧
    在这里插入图片描述
  • 如何右旋转
    在这里插入图片描述
  • 插入的元素在不平衡的节点的右侧的右侧
    在这里插入图片描述
  • 插入的元素在不平衡的节点的左侧的右侧
    在这里插入图片描述
  • 插入的元素在不平衡的节点的右侧的左侧
    在这里插入图片描述

代码实现

  • 构造结点
  • 辅助函数获取高度
  • 获取结的平衡因子
  • 判断该树是一颗二分搜索树
  • 判断该树是一颗平衡二叉树
package AVLTree;

import reflect.Map;
import tree.LinkedSet;
import tree.Set;
import dyarray.ArrayList;
import dyarray.MyArrayList;
import dyarray.MyList;
import dylist.LinkedList;

public class AVLTree<K extends Comparable<K>, V> implements Map<K, V> {
	private class Node {
		public K k;
		public V v;
		public Node left, right;
		public int height;

		public Node(K k, V v) {
			this.k = k;
			this.v = v;
			left = null;
			right = null;
			height = 1;
		}

		public Node() {
			this(null, null);
		}

		@Override
		public String toString() {
			// TODO Auto-generated method stub
			return k + ":" + v;
		}

	}

	private Node root;
	private int size;

	public AVLTree() {
		root = null;
		size = 0;
	}

	// 获取高度
	private int getHeight(Node node) {
		if (node == null) {
			return 0;
		}
		return node.height;
	}

	// 获取平衡因子
	private int getBalanceFator(Node node) {
		if (node == null) {
			return 0;
		}
		return getHeight(node.left) - getHeight(node.right);
	}

	// 判断该树是一颗二分搜索树
	public boolean isBinarySearch() {
		MyList<K> list = new MyArrayList<>();
		midOrderKey(root, list);
		for (int i = 1; i < list.getSize(); i++) {
			if (list.get(i).compareTo(list.get(i - 1)) < 0) {
				return false;
			}
		}
		return true;
	}

	// 中序遍历所有的键
	private void midOrderKey(Node node, MyList<K> list) {
		if (node == null) {
			return;
		}
		midOrderKey(node.left, list);
		list.addLast(node.k);
		midOrderKey(node.right, list);
	}

	// 判断该树是一颗平衡二叉树
	public boolean isBalance() {
		return isBalance(root);
	}

	private boolean isBalance(Node node) {
		if (node == null) {
			return true;
		}
		//System.out.println(node.k+":"+getBalanceFator(node));
		if (Math.abs(getBalanceFator(node)) > 1) {
			return false;
		}
		return isBalance(node.left) && isBalance(node.right);
	}

	// 辅助寻找方法
	private Node getNode(K k) {
		return getNode(root, k);
	}

	private Node getNode(Node node, K k) {
		if (node == null) {
			return null;
		}
		if (k.compareTo(node.k) < 0) {
			return getNode(node.left, k);
		} else if (k.compareTo(node.k) > 0) {
			return getNode(node.right, k);
		} else {
			return node;
		}
	}

	@Override
	public void add(K k, V v) {
		root = add(root, k, v);
	}

	private Node add(Node node, K k, V v) {
		if (node == null) {
			size++;
			return new Node(k, v);
		}
		if (k.compareTo(node.k) < 0) {
			node.left = add(node.left, k, v);
		} else if (k.compareTo(node.k) > 0) {
			node.right = add(node.right, k, v);
		} else {
			node.v = v;
		}
		// 更新高度
		node.height =1+Math.max(getHeight(node.left), getHeight(node.right));
		// 平衡因子
		int balance = getBalanceFator(node);
		// 左侧的左侧
		if (balance > 1 && getBalanceFator(node.left) >= 0) {
			return rightRoll(node); 
		}
		// 左侧的右侧
		if (balance > 1 && getBalanceFator(node.left) < 0) {
			node.left = leftRoll(node.left);
			return rightRoll(node);
		}
		// 右侧的右侧
		if (balance < -1 && getBalanceFator(node.right)<=0) {
			return leftRoll(node);
		}
		// 右侧的左侧
		if (balance < -1 && getBalanceFator(node.right)>0) {
			node.right = rightRoll(node.right);
			return leftRoll(node);
		}
		return node;
	}

	// 右旋LL
	private Node rightRoll(Node node) {
		Node x = node.left;
		node.left=x.right;
		x.right=node;
		node.height =1+Math.max(getHeight(node.left),getHeight(node.right));
		x.height =1+Math.max(getHeight(node.left),getHeight(node.right));
		return x;
	}

	// 左旋RR
	private Node leftRoll(Node node) {
		Node x = node.right;
		node.right = x.left;
		x.left = node;
		node.height =1+Math.max(getHeight(node.left), getHeight(node.right));
		x.height =1+Math.max(getHeight(node.left), getHeight(node.right));
		return x;
	}

	// 左右旋LR

	// 右左旋RL

	@Override
	public V remove(K k) {
		Node n = getNode(k);
		if (n == null) {
			return null;
		}
		root = remove(root, k);
		return n.v;
	}

	private Node remove(Node node, K k) {
		if (node == null) {
			return null;
		}
		Node re = null;
		if (k.compareTo(node.k) < 0) {
			node.left = remove(node.left, k);
			re = node;
		} else if (k.compareTo(node.k) > 0) {
			node.right = remove(node.right, k);
			re = node;
		} else {
			// 左子树为null
			if (node.left == null) {
				Node right = node.right;
				node = null;
				size--;
				re = right;
			} else if (node.right == null) {
				Node left = node.right;
				node = null;
				size--;
				re = left;
			} else {
				Node tim = min(node.right);
				tim.right = remove(node.right, tim.k);
				tim.left = node.left;
				re = tim;
			}
		}
		if (re == null) {
			return null;
		}
		//删除之后只有re结点的高度有变化
		//从最后一个结点回溯
		// 更新高度
		re.height =1+Math.max(getHeight(re.left), getHeight(re.right));
		// 平衡因子
		int balance = getBalanceFator(re);
		// 左侧的左侧
		if (balance > 1 && getBalanceFator(re.left) >= 0) {
			return rightRoll(re);
		}
		// 左侧的右侧
		if (balance > 1 && getBalanceFator(re.left) < 0) {
			re.left = leftRoll(re.left);
			return rightRoll(re);
		}
		// 右侧的右侧
		if (balance < -1 && getBalanceFator(re.right) <= 0) {
			return leftRoll(re);
		}
		// 右侧的左侧
		if (balance < -1 && getBalanceFator(re.right) > 0) {
			re.right = rightRoll(re.right);
			return leftRoll(node);
		}
		return re;
	}
	// 找到最小值
	private Node min(Node node) {
		if (node.left == null) {
			return node;
		} else {
			return min(node.left);
		}
	}
	// 删除最小值
	private Node removeMin(Node node) {
		if (node.left == null) {
			Node nodeRight = node.right;
			node = null;
			size--;
			return nodeRight;
		}
		node.left = removeMin(node.left);
		return node;
	}

	@Override
	public boolean contains(K k) {
		return getNode(k) != null;
	}

	@Override
	public V get(K k) {
		return getNode(k).v;
	}

	@Override
	public void set(K k, V v) {
		Node n = getNode(k);
		if (n == null) {
			throw new IllegalArgumentException();
		}
		n.v = v;
	}

	@Override
	public Set keys() {
		Set<K> set = new LinkedSet<>();
		midOrder(root, set);
		return set;
	}

	// 返回keys的中序遍历
	private void midOrder(Node node, Set<K> set) {
		if (node == null) {
			return;
		}
		midOrder(node.left, set);
		set.add(node.k);
		midOrder(node.right, set);
	}

	@Override
	public MyList<V> values() {
		MyList<V> list = new LinkedList<>();
		midOrder(root, list);
		return list;
	}

	// 中序遍历返回所有值
	private void midOrder(Node node, MyList<V> list) {
		if (node == null) {
			return;
		}
		midOrder(node.left, list);

		list.addLast(node.v);

		midOrder(node.right, list);
	}

	@Override
	public int getSize() {
		// TODO Auto-generated method stub
		return size;
	}

	@Override
	public boolean isEmpty() {
		// TODO Auto-generated method stub
		return size == 0;
	}

}

猜你喜欢

转载自blog.csdn.net/zhang_ye_ye/article/details/89433814
今日推荐