java实现二叉平衡树

节点数据结构:
class Node {
int balanceDegree;//结点有平衡度(左子树高 -  右子树高), 在 [-1,01] 表示当前节点是平衡的
int val;
Node left,right,parent;// 左/右子树,parent指向父节点
}
插入数据需要调节平衡度,
(1) 插入节点 i
(2)从i节点开始向上回溯到根节点
(3)如果i节点是其父节点的左子树 则父节点平衡度+1 否则 父节点平衡度-1
(4) 如果 父节点平衡度为0 ,则执行 (7)
(5) 判断父节点平衡度是否在 [-1,0,1]之间,若不在,调整父节点的平衡度,执行(7)
(6) i=i.parent 执行(3)
(7)退出

调整节点的平衡度:

旋转,LL型(节点平衡度是2,左子树平衡度为 1) 通过右旋转达到平衡,LR(节点平衡度是2,左子树平衡度为 -1) 能过左旋转转成 LL 型

RR型(节点平衡度是-2,右子树平衡度为 -1) 通过左 旋转达到平衡,RL(节点平衡度是-2,右子树平衡度为 1) 能过右旋转转成 RR型

LR->LL ->平衡
RL->RR->平衡

旋转时要注意各节点的父指针及左右子树的设置


class Node {
	int val, balanceDegree;
	Node left, right, parent;

	public Node(int val) {
		this.val = val;
		this.left = this.right = this.parent = null;
	}

	public int getbalanceDegree() {
		return this.balanceDegree;
	}

	public String toString() {
		return "[" + this.val + "," + this.getbalanceDegree() + "," + (this.parent == null ? "null" : this.parent.val)
				+ "]";
	}
}

public class AVLTree {
	Node root;

	public AVLTree() {
		this.root = null;
	}

	private void _midTravel(Node n) {
		if (n == null)
			return;
		this._midTravel(n.left);
		System.out.print(n.toString() + " ");
		this._midTravel(n.right);
	}

	public void midTravel() {
		this._midTravel(root);
	}

	public void setChildrenParent(Node n) {
		if (n == null)
			return;
		if (n.left != null)
			n.left.parent = n;
		if (n.right != null)
			n.right.parent = n;
	}

	public Node rightRotate(Node node) {
		if (node == null || node.left == null)
			return node;
		Node l = node.left;
		node.left = l.right;
		l.right = node;
		l.parent = node.parent;
		node.parent = l;
		if (l.parent != null) {
			if (l.parent.left == node) {
				l.parent.left = l;
			} else {
				l.parent.right = l;
			}
		}
		this.setChildrenParent(l.left);
		this.setChildrenParent(l.right);
		return l;
	}

	public Node leftRotate(Node node) {
		if (node == null || node.right == null)
			return node;
		Node r = node.right;
		node.right = r.left;
		r.left = node;
		r.parent = node.parent;
		node.parent = r;
		if (r.parent != null) {
			if (r.parent.left == node) {
				r.parent.left = r;
			} else {
				r.parent.right = r;
			}
		}
		this.setChildrenParent(r.left);
		this.setChildrenParent(r.right);
		return r;
	}

	public void delVal(int val) {

	}

	public void insertVal(int val) {
		if (root == null) {
			this.root = new Node(val);
		} else {
			Node n = this.root, p = n;
			Node i = new Node(val);
			while (n != null) {
				p = n;
				if (n.val >= val) {
					n = n.left;
				} else {
					n = n.right;
				}
			}
			i.parent = p;
			if (p.val > val)
				p.left = i;
			else
				p.right = i;
			/**/
			while ((p = i.parent) != null) {
				if (p.left == i)
					p.balanceDegree++;
				else
					p.balanceDegree--;
				// 树的高度不变,直接退出循环
				if (p.balanceDegree == 0)
					break;
				if (p.balanceDegree == 2) {
					if (p.left != null && p.left.balanceDegree == 1) {
						// LL型
						p = this.rightRotate(p);
					} else {
						// LR型
						this.leftRotate(p.left);
						p = this.rightRotate(p);
						p.left.balanceDegree = p.balanceDegree >= 0 ? 0 : 1;
					}
					p.balanceDegree = 0;
					p.right.balanceDegree = 0;
					break;
				} else if (p.balanceDegree == -2) {
					if (p.left != null && p.left.balanceDegree == 1) {
						// RL型
						this.rightRotate(p.right);
						p = this.leftRotate(p);
						p.right.balanceDegree = p.balanceDegree >= 0 ? 0 : 1;
					} else {
						// RR型
						p = this.leftRotate(p);
					}
					i = p.left;
					p.balanceDegree = 0;
					i.balanceDegree = 0;
					break;
				}
				i = p;
				p = i.parent;
			}
			while (this.root.parent != null)
				this.root = this.root.parent;
		}
		System.out.println("insert :" + val);
		this.leveleTravle();
		System.out.println("---------------");
	}

	public void leveleTravle() {
		if (this.root == null)
			return;
		List<Node> q = new ArrayList<Node>();
		List<Node> q1 = new ArrayList<Node>();
		List<Node> t;
		q.add(this.root);
		while (!q.isEmpty()) {
			for (Node n : q) {
				if (n == null) {
					System.out.print("[#]\t");
					continue;
				}

				System.out.print(n.toString() + "\t");
				q1.add(n.left);
				q1.add(n.right);
			}
			q.clear();
			t = q1;
			q1 = q;
			q = t;
			System.out.println();
		}
	}

	public void insertVals(int[] data) {
		for (int d : data) {
			this.insertVal(d);
		}
	}

	private int _hight(Node n) {
		if (n == null)
			return 0;
		return 1 + Math.max(this._hight(n.left), this._hight(n.right));
	}

	public int hight() {
		return this._hight(this.root);
	}

	public static void main(String[] args) {
		AVLTree tree = new AVLTree();
		tree.insertVals(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 });
		System.out.println(tree.hight());
		tree.midTravel();
		// System.out.println();
		// tree.leveleTravle();
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值