一、基础知识
二、AVL树高度求解
package com.ws.数据结构.树.平衡二叉树AVL.创建与高度;
public class AVLTree {
public static void main(String[] args) {
int[] arr={4,3,6,5,7,8};
//创建平衡二叉树对象
AVL avl=new AVL();
//添加节点
for (int i=0;i<arr.length;i++){
avl.add(new Node(arr[i]));
}
//遍历平衡二叉树
System.out.println("遍历平衡二叉树");
avl.zhongprintf();
System.out.println("没有旋转之前");
System.out.println("树的高度="+avl.getRoot().height());
System.out.println("左子树的高度="+avl.getRoot().zuoHeight());
System.out.println("右子树的高度="+avl.getRoot().youHeight());
}
}
//创建节点
class Node{
int value;
Node zuo;
Node you;
public Node(int value) {
this.value = value;
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}
//添加节点
//递归形式添加平衡二叉排序树
public void add(Node node){
if (node==null){
return;
}
//判断传入节点值和子树的根节点的值的关系
if (node.value<this.value){
//小于 当前树左子节点为空,就直接挂上
if (this.zuo==null){
this.zuo=node;
}else {
//递归左子树添加
this.zuo.add(node);
}
}else {
//大于 当前右子节点为空,就直接挂上
if (this.you==null){
this.you=node;
}else {
//递归向右子树添加
this.you.add(node);
}
}
}
//中序遍历
public void zhongprintf(){
if (this.zuo!=null){
this.zuo.zhongprintf();
}
System.out.println(this);
if (this.you!=null){
this.you.zhongprintf();
}
}
//返回当前节点的高度 以该节点为根节点的树的高度
public int height(){
return Math.max(zuo==null?0:zuo.height(),you==null?0:you.height())+1;
}
//返回左子树的额高度
public int zuoHeight(){
if (zuo==null){
return 0;
}
return zuo.height();
}
//返回右子树的高度
public int youHeight(){
if (you==null){
return 0;
}
return you.height();
}
}
//创建AVL树
class AVL{
private Node root;
public Node getRoot() {
return root;
}
//添加节点方法
public void add(Node node){
//根节点是空,就直接添加
if (root==null){
root=node;
}else {
root.add(node);
}
}
//中序遍历
public void zhongprintf(){
if (root!=null){
root.zhongprintf();
}else {
System.out.println("当前平衡二叉树为空,不能遍历");
}
}
}
遍历平衡二叉树
Node{value=3}
Node{value=4}
Node{value=5}
Node{value=6}
Node{value=7}
Node{value=8}
没有旋转之前
树的高度=4
左子树的高度=1
右子树的高度=3
三、AVL树左旋转
package com.ws.数据结构.树.平衡二叉树AVL.左旋转;
public class AVLTree {
public static void main(String[] args) {
int[] arr={4,3,6,5,7,8};
//创建平衡二叉树对象
AVL avl=new AVL();
//添加节点
for (int i=0;i<arr.length;i++){
avl.add(new Node(arr[i]));
}
//遍历平衡二叉树
System.out.println("遍历平衡二叉树");
avl.zhongprintf();
System.out.println("旋转之后");
System.out.println("树的高度="+avl.getRoot().height());//4
System.out.println("左子树的高度="+avl.getRoot().zuoHeight());//1
System.out.println("右子树的高度="+avl.getRoot().youHeight());//3
}
}
//创建节点
class Node{
int value;
Node zuo;
Node you;
public Node(int value) {
this.value = value;
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}
//添加节点
//递归形式添加平衡二叉排序树
public void add(Node node){
if (node==null){
return;
}
//判断传入节点值和子树的根节点的值的关系
if (node.value<this.value){
//小于 当前树左子节点为空,就直接挂上
if (this.zuo==null){
this.zuo=node;
}else {
//递归左子树添加
this.zuo.add(node);
}
}else {
//大于 当前右子节点为空,就直接挂上
if (this.you==null){
this.you=node;
}else {
//递归向右子树添加
this.you.add(node);
}
}
//当添加完节点后,如果(右子树的高度-左子树的高度)>1就进行旋转(左旋转)(avl树的特点)
if (youHeight()-zuoHeight()>1){
zuoRotate();//左旋转
}
}
//中序遍历
public void zhongprintf(){
if (this.zuo!=null){
this.zuo.zhongprintf();
}
System.out.println(this);
if (this.you!=null){
this.you.zhongprintf();
}
}
//返回当前节点的高度 以该节点为根节点的树的高度
public int height(){
return Math.max(zuo==null?0:zuo.height(),you==null?0:you.height())+1;
}
//返回左子树的额高度
public int zuoHeight(){
if (zuo==null){
return 0;
}
return zuo.height();
}
//返回右子树的高度
public int youHeight(){
if (you==null){
return 0;
}
return you.height();
}
//左旋转
private void zuoRotate(){
//创建新的节点,值是当前节点
Node newNode=new Node(value);
//把新的节点的左子树设置成当前节点的左子树
newNode.zuo=zuo;
//把新节点的右子树设置成当前节点的右子树的左子树
newNode.you=you.zuo;
//把当前节点的值换成右子树的值
value=you.value;
//把当前节点的右子树设置成当前节点的右子树的右子树
you=you.you;
//把当前节点的左子节点设置成新的节点
zuo=newNode;
}
}
//创建AVL树
class AVL{
private Node root;
public Node getRoot() {
return root;
}
//添加节点方法
public void add(Node node){
//根节点是空,就直接添加
if (root==null){
root=node;
}else {
root.add(node);
}
}
//中序遍历
public void zhongprintf(){
if (root!=null){
root.zhongprintf();
}else {
System.out.println("当前平衡二叉树为空,不能遍历");
}
}
}
遍历平衡二叉树
Node{value=3}
Node{value=4}
Node{value=5}
Node{value=6}
Node{value=7}
Node{value=8}
旋转之后
树的高度=3
左子树的高度=2
右子树的高度=2
四、AVL树右旋转
package com.ws.数据结构.树.平衡二叉树AVL.右旋转;
public class AVLTree {
public static void main(String[] args) {
//int[] arr={4,3,6,5,7,8};
int[] arr={10,12,8,9,7,6};
//创建平衡二叉树对象
AVL avl=new AVL();
//添加节点
for (int i=0;i<arr.length;i++){
avl.add(new Node(arr[i]));
}
//遍历平衡二叉树
System.out.println("遍历平衡二叉树");
avl.zhongprintf();
System.out.println("旋转之后");
System.out.println("树的高度="+avl.getRoot().height());//4
System.out.println("左子树的高度="+avl.getRoot().zuoHeight());//3
System.out.println("右子树的高度="+avl.getRoot().youHeight());//1
System.out.println("当前根节点="+avl.getRoot());//8
}
}
//创建节点
class Node{
int value;
Node zuo;
Node you;
public Node(int value) {
this.value = value;
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}
//添加节点
//递归形式添加平衡二叉排序树
public void add(Node node){
if (node==null){
return;
}
//判断传入节点值和子树的根节点的值的关系
if (node.value<this.value){
//小于 当前树左子节点为空,就直接挂上
if (this.zuo==null){
this.zuo=node;
}else {
//递归左子树添加
this.zuo.add(node);
}
}else {
//大于 当前右子节点为空,就直接挂上
if (this.you==null){
this.you=node;
}else {
//递归向右子树添加
this.you.add(node);
}
}
//当添加完节点后,如果(右子树的高度-左子树的高度)>1就进行旋转(左旋转)(avl树的特点)
if (youHeight()-zuoHeight()>1){
zuoRotate();//左旋转
}
//当添加完一个节点后(左子树高度-右子树高度)>1就进行右旋转
if (zuoHeight()-youHeight()>1){
youRotate();//右旋转
}
}
//中序遍历
public void zhongprintf(){
if (this.zuo!=null){
this.zuo.zhongprintf();
}
System.out.println(this);
if (this.you!=null){
this.you.zhongprintf();
}
}
//返回当前节点的高度 以该节点为根节点的树的高度
public int height(){
return Math.max(zuo==null?0:zuo.height(),you==null?0:you.height())+1;
}
//返回左子树的额高度
public int zuoHeight(){
if (zuo==null){
return 0;
}
return zuo.height();
}
//返回右子树的高度
public int youHeight(){
if (you==null){
return 0;
}
return you.height();
}
//左旋转
private void zuoRotate(){
//创建新的节点,值是当前节点
Node newNode=new Node(value);
//把新的节点的左子树设置成当前节点的左子树
newNode.zuo=zuo;
//把新节点的右子树设置成当前节点的右子树的左子树
newNode.you=you.zuo;
//把当前节点的值换成右子树的值
value=you.value;
//把当前节点的右子树设置成当前节点的右子树的右子树
you=you.you;
//把当前节点的左子节点设置成新的节点
zuo=newNode;
}
//右旋转
private void youRotate(){
//创建新的节点,值是当前节点
Node newNode=new Node(value);
//把新节点的右子树设置成当前节点的右子树
newNode.you=you;
//把新节点的左子节点指向当前节点的左子节点的右子节点
newNode.zuo=zuo.you;
//把当前节点的值改成左子节点的值
value=zuo.value;
//把当前节点的左子节点指向左子节点的左子节点
zuo=zuo.zuo;
//当前节点的右子节点指向新节点
you=newNode;
}
}
//创建AVL树
class AVL{
private Node root;
public Node getRoot() {
return root;
}
//添加节点方法
public void add(Node node){
//根节点是空,就直接添加
if (root==null){
root=node;
}else {
root.add(node);
}
}
//中序遍历
public void zhongprintf(){
if (root!=null){
root.zhongprintf();
}else {
System.out.println("当前平衡二叉树为空,不能遍历");
}
}
}
遍历平衡二叉树
Node{value=6}
Node{value=7}
Node{value=8}
Node{value=9}
Node{value=10}
Node{value=12}
旋转之后
树的高度=3
左子树的高度=2
右子树的高度=2
当前根节点=Node{value=8}
五、AVL树双旋转
package com.ws.数据结构.树.平衡二叉树AVL.双旋转;
public class AVLTree {
public static void main(String[] args) {
//int[] arr={4,3,6,5,7,8};
int[] arr={10,12,8,9,7,6};
//创建平衡二叉树对象
AVL avl=new AVL();
//添加节点
for (int i=0;i<arr.length;i++){
avl.add(new Node(arr[i]));
}
//遍历平衡二叉树
System.out.println("遍历平衡二叉树");
avl.zhongprintf();
System.out.println("旋转之后");
System.out.println("树的高度="+avl.getRoot().height());//4
System.out.println("左子树的高度="+avl.getRoot().zuoHeight());//3
System.out.println("右子树的高度="+avl.getRoot().youHeight());//1
System.out.println("当前根节点="+avl.getRoot());//8
}
}
//创建节点
class Node{
int value;
Node zuo;
Node you;
public Node(int value) {
this.value = value;
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}
//添加节点
//递归形式添加平衡二叉排序树
public void add(Node node){
if (node==null){
return;
}
//判断传入节点值和子树的根节点的值的关系
if (node.value<this.value){
//小于 当前树左子节点为空,就直接挂上
if (this.zuo==null){
this.zuo=node;
}else {
//递归左子树添加
this.zuo.add(node);
}
}else {
//大于 当前右子节点为空,就直接挂上
if (this.you==null){
this.you=node;
}else {
//递归向右子树添加
this.you.add(node);
}
}
//当添加完节点后,如果(右子树的高度-左子树的高度)>1就进行旋转(左旋转)(avl树的特点)
if (youHeight()-zuoHeight()>1){
//如果它的右子树的左子树的高度大于他的右子树的右子树的高度
if (you!=null&&you.zuoHeight()>you.youHeight()){
//先进行对右子节点右旋转
you.youRotate();
// 再对当前节点进行左旋转
zuoRotate();
}else {
//直接进行左旋转
zuoRotate();//左旋转
}
return;//平衡后立马返回,要不会进入下一个if
}
//当添加完一个节点后(左子树高度-右子树高度)>1就进行右旋转
if (zuoHeight()-youHeight()>1){
//如果他左子树的右子树的高度大于他左子树的高度
if (zuo!=null&&zuo.you.youHeight()>zuo.zuoHeight()){
//先对左子树左旋转
zuo.zuoRotate();
//再对当前节点进行右旋转
youRotate();
}else {
//直接进行右旋转即可
youRotate();//右旋转
}
}
}
//中序遍历
public void zhongprintf(){
if (this.zuo!=null){
this.zuo.zhongprintf();
}
System.out.println(this);
if (this.you!=null){
this.you.zhongprintf();
}
}
//返回当前节点的高度 以该节点为根节点的树的高度
public int height(){
return Math.max(zuo==null?0:zuo.height(),you==null?0:you.height())+1;
}
//返回左子树的额高度
public int zuoHeight(){
if (zuo==null){
return 0;
}
return zuo.height();
}
//返回右子树的高度
public int youHeight(){
if (you==null){
return 0;
}
return you.height();
}
//左旋转
private void zuoRotate(){
//创建新的节点,值是当前节点
Node newNode=new Node(value);
//把新的节点的左子树设置成当前节点的左子树
newNode.zuo=zuo;
//把新节点的右子树设置成当前节点的右子树的左子树
newNode.you=you.zuo;
//把当前节点的值换成右子树的值
value=you.value;
//把当前节点的右子树设置成当前节点的右子树的右子树
you=you.you;
//把当前节点的左子节点设置成新的节点
zuo=newNode;
}
//右旋转
private void youRotate(){
//创建新的节点,值是当前节点
Node newNode=new Node(value);
//把新节点的右子树设置成当前节点的右子树
newNode.you=you;
//把新节点的左子节点指向当前节点的左子节点的右子节点
newNode.zuo=zuo.you;
//把当前节点的值改成左子节点的值
value=zuo.value;
//把当前节点的左子节点指向左子节点的左子节点
zuo=zuo.zuo;
//当前节点的右子节点指向新节点
you=newNode;
}
}
//创建AVL树
class AVL{
private Node root;
public Node getRoot() {
return root;
}
//添加节点方法
public void add(Node node){
//根节点是空,就直接添加
if (root==null){
root=node;
}else {
root.add(node);
}
}
//中序遍历
public void zhongprintf(){
if (root!=null){
root.zhongprintf();
}else {
System.out.println("当前平衡二叉树为空,不能遍历");
}
}
}
遍历平衡二叉树
Node{value=6}
Node{value=7}
Node{value=8}
Node{value=9}
Node{value=10}
Node{value=12}
旋转之后
树的高度=3
左子树的高度=2
右子树的高度=2
当前根节点=Node{value=8}