平衡二叉树也叫平衡二叉搜索树(Self-balancing binary search tree)又被称为AVL树, 可以保证查询效率较高。 具有以下特点:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、Treap、伸展树等。平衡二叉树也是二叉排序树
案例:图一图二是平衡二叉树,图三不是
左旋转:
主要代码:int[] arr = {4,3,6,5,7,8}
/**
* 返回左子树高度
*/
public int leftHeight(){
if (this.left == null){
return 0;
}
return this.left.height();
}
/**
* 返回左子树高度
*/
public int rightHeight(){
if (this.right == null){
return 0;
}
return this.right.height();
}
/**
* 返回当前结点的树的最大高度
*/
public int height(){
return Math.max(this.left == null ? 0 : this.left.height(),this.right == null ? 0 :this.right.height())+1;
}
/**
* 左旋转
*/
private void leftRotate(){
//1:以当前结点创建新的节点
Node newNode = new Node(value);
//2:新结点的左结点是当前结点的左结点
newNode.left = this.left;
//3:新结点的右结点是当前结点的右结点的左结点
newNode.right = this.right.left;
//4:把当前结点的值换成当前结点右子节点的值
this.value = this.right.value;
//5:当前结点右子树设置成当前结点的右子树的右子树
this.right = this.right.right;
//6:当前结点左子树设置成新节点
this.left = newNode;
}
右旋转:
/**
* 右旋转
*/
private void rightRotate(){
//1:以当前结点创建新的节点
Node newNode = new Node(value);
//2:新结点的右结点是当前结点的右结点
newNode.right = this.right;
//3:新结点的左结点是当前结点的左结点的右结点
newNode.left = this.left.right;
//4:把当前结点的值换成当前结点左子节点的值
this.value = this.left.value;
//5:当前结点左子树设置成当前结点的左子树的左子树
this.left = this.left.left;
//6:当前结点右子树设置成新节点
this.right = newNode;
}
双旋转:
//添加一个结点后判断右子树高度-左子树高度>1,则左旋转
if(rightHeight()-leftHeight()>1){
if(this.right != null && this.right.leftHeight()>this.right.rightHeight()){
//当前结点的右结点右旋转
this.right.rightRotate();
leftRotate();
}else {
leftRotate();
}
}
//添加一个结点后判断左子树高度-右子树高度>1,则右旋转
if(leftHeight()-rightHeight()>1){
if(this.left != null && this.left.rightHeight()>this.left.leftHeight()){
//当前结点的左结点左旋转
this.left.leftRotate();
rightRotate();
}else {
rightRotate();
}
}
完整代码
package com.atgguigu.avl;
public class AVLTreeDemo {
public static void main(String[] args) {
int[] arr = {4,3,6,5,7,8};
int[] arr2 = {10,12,8,9,7,6};
AVLTree avlTree = new AVLTree();
for (int i : arr2) {
avlTree.add(new Node(i));
}
System.out.println("=============平衡处理后的中序遍历==========");
avlTree.infixOrder();
System.out.println("================平衡处理后===============");
System.out.println("当前根节点:"+avlTree.getRoot());
int height = avlTree.getRoot().height();
System.out.println("树的高度="+height);
System.out.println("左子树的高度="+avlTree.getRoot().leftHeight());
System.out.println("右子树的高度="+avlTree.getRoot().rightHeight());
}
}
class AVLTree{
private Node root;
public Node getRoot() {
return root;
}
public void setRoot(Node root) {
this.root = root;
}
public void add(Node node){
if(root == null){
root =node;
}else {
root.add(node);
}
}
public void infixOrder(){
if(root != null){
root.infixOrder();
}else {
System.out.println("二叉排序树为空");
}
}
}
//节点
class Node{
int value;
Node left;
Node right;
public Node(int value) {
this.value = value;
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}
/**
* 返回左子树高度
*/
public int leftHeight(){
if (this.left == null){
return 0;
}
return this.left.height();
}
/**
* 返回左子树高度
*/
public int rightHeight(){
if (this.right == null){
return 0;
}
return this.right.height();
}
/**
* 返回当前结点的树的最大高度
*/
public int height(){
return Math.max(this.left == null ? 0 : this.left.height(),this.right == null ? 0 :this.right.height())+1;
}
/**
* 左旋转
*/
private void leftRotate(){
//1:以当前结点创建新的节点
Node newNode = new Node(value);
//2:新结点的左结点是当前结点的左结点
newNode.left = this.left;
//3:新结点的右结点是当前结点的右结点的左结点
newNode.right = this.right.left;
//4:把当前结点的值换成当前结点右子节点的值
this.value = this.right.value;
//5:当前结点右子树设置成当前结点的右子树的右子树
this.right = this.right.right;
//6:当前结点左子树设置成新节点
this.left = newNode;
}
/**
* 右旋转
*/
private void rightRotate(){
//1:以当前结点创建新的节点
Node newNode = new Node(value);
//2:新结点的右结点是当前结点的右结点
newNode.right = this.right;
//3:新结点的左结点是当前结点的左结点的右结点
newNode.left = this.left.right;
//4:把当前结点的值换成当前结点左子节点的值
this.value = this.left.value;
//5:当前结点左子树设置成当前结点的左子树的左子树
this.left = this.left.left;
//6:当前结点右子树设置成新节点
this.right = newNode;
}
//添加节点
public void add(Node node){
if(node == null){
return;
}
//添加左边
if(node.value < this.value){
if(this.left == null){
this.left = node;
}else {
this.left.add(node);
}
}
//添加右边
if(node.value >= this.value){
if(this.right == null){
this.right = node;
}else {
this.right.add(node);
}
}
//添加一个结点后判断右子树高度-左子树高度>1,则左旋转
if(rightHeight()-leftHeight()>1){
if(this.right != null && this.right.leftHeight()>this.right.rightHeight()){
//当前结点的右结点右旋转
this.right.rightRotate();
leftRotate();
}else {
leftRotate();
}
return;
}
//添加一个结点后判断左子树高度-右子树高度>1,则右旋转
if(leftHeight()-rightHeight()>1){
if(this.left != null && this.left.rightHeight()>this.left.leftHeight()){
//当前结点的左结点左旋转
this.left.leftRotate();
rightRotate();
}else {
rightRotate();
}
}
}
//中序遍历
public void infixOrder(){
if(this.left != null){
this.left.infixOrder();
}
System.out.println(this);
if(this.right != null){
this.right.infixOrder();
}
}
}