AVL树

  1 package AVLTree2;
  2 
  3 public class AVLTreeDemo {
  4 
  5     public static void main(String[] args) {
  6         AVLTree t = new AVLTree();
  7 
  8         t.insert(4);
  9         t.insert(5);
 10         t.insert(3);
 11         t.preOrder();
 12 
 13     }
 14 
 15 }
 16 
 17 class AVLTree {
 18 
 19     Node root = null;
 20 
 21     Node temp = new Node(-1);
 22 
 23     // 添加节点
 24     public void insert(int no) {
 25         root = temp.insert(no, root);
 26     }
 27 
 28     // 前序遍历
 29     public void preOrder() {
 30         if (this.root == null) {
 31             System.out.println("此树为空!!!");
 32         } else {
 33             this.root.preOrder();
 34         }
 35     }
 36 }
 37 
 38 class Node {
 39     int value;
 40     Node left;
 41     Node right;
 42 
 43     public Node(int value) {
 44         super();
 45         this.value = value;
 46     }
 47 
 48     @Override
 49     public String toString() {
 50         return value + " ";
 51     }
 52 
 53     // 获取树的高度
 54     public int getHeight() {
 55         return Math.max(left == null ? 0 : left.getHeight(), right == null ? 0 : right.getHeight()) + 1;
 56 
 57     }
 58 
 59     // 获取左子树的高度
 60     public int getLeftHeight() {
 61         if (left == null) {
 62             return 0;
 63         }
 64         return left.getHeight();
 65 
 66     }
 67 
 68     // 获取右子树的高度
 69     public int getRightHeight() {
 70         if (right == null) {
 71             return 0;
 72         }
 73         return right.getHeight();
 74     }
 75 
 76     // 添加节点
 77     public Node insert(int no, Node t) {
 78         if (t == null) {
 79             return new Node(no);
 80         }
 81 
 82         int comResult = no - t.value;
 83 
 84         if (comResult < 0) {
 85             t.left = insert(no, t.left);
 86         }
 87 
 88         if (comResult > 0) {
 89             t.right = insert(no, t.right);
 90         }
 91 
 92         return balance(t);
 93     }
 94 
 95     public Node balance(Node t) {
 96         if (t == null) {
 97             return t;
 98         }
 99 
100         // 左子树高度>右子树高度
101         if (t.getLeftHeight() - t.getRightHeight() > 1) {
102             if (t.left.getLeftHeight() >= t.left.getRightHeight()) {
103                 t = turnLeft(t);
104             } else {
105                 t.left = turnRight(t.left);
106                 t = turnLeft(t);
107             }
108         }
109 
110         // 右子树高度>左子树高度
111         if (t.getRightHeight() - t.getLeftHeight() > 1) {
112             if (t.right.getRightHeight() >= t.right.getLeftHeight()) {
113                 t = turnRight(t);
114             } else {
115                 t.right = turnRight(t.right);
116                 t = turnRight(t);
117             }
118         }
119 
120         return t;
121 
122     }
123 
124     // 左旋转:左子树高度-右子树高度>1时,将左边的子树向右旋转
125     public Node turnLeft(Node t) {
126         Node newroot = t.left;
127         t.left = newroot.right;
128         return newroot;
129     }
130 
131     // 右旋转:右子树高度-左子树高度>1时,将右边的子树向做旋转
132     public Node turnRight(Node t) {
133         Node newroot = t.right;
134         t.right = newroot.left;
135         return newroot;
136     }
137 
138     // 前序遍历
139     public void preOrder() {
140         System.out.println(this);
141         if (this.left != null) {
142             this.left.preOrder();
143         }
144 
145         if (this.right != null) {
146             this.right.preOrder();
147         }
148     }
149 
150 }

存在问题:

  若将添加顺序改为:3、4、5

带来的影响如下图:3没有被打出来,通过上面的结果,可以知道,添加节点过程应该是没有问题的,不会存在左节点不添加的问题,所以估计问题出在了旋转调整部分:

第一版修改:

成功

测试:

顺序输入1到10

package AVLTree2;

public class AVLTreeDemo {

    public static void main(String[] args) {
        AVLTree t = new AVLTree();
        for (int i = 1; i <=10; i++) {
            t.insert(i);
        }
        t.preOrder();

    }

}

class AVLTree {

    Node root = null;

    Node temp = new Node(-1);

    // 添加节点
    public void insert(int no) {
        root = temp.insert(no, root);
    }

    // 前序遍历
    public void preOrder() {
        if (this.root == null) {
            System.out.println("此树为空!!!");
        } else {
            this.root.preOrder();
        }
    }
}

class Node {
    int value;
    Node left;
    Node right;

    public Node(int value) {
        super();
        this.value = value;
    }

    @Override
    public String toString() {
        return value + " ";
    }

    // 获取树的高度
    public int getHeight() {
        return Math.max(left == null ? 0 : left.getHeight(), right == null ? 0 : right.getHeight()) + 1;

    }

    // 获取左子树的高度
    public int getLeftHeight() {
        if (left == null) {
            return 0;
        }
        return left.getHeight();

    }

    // 获取右子树的高度
    public int getRightHeight() {
        if (right == null) {
            return 0;
        }
        return right.getHeight();
    }

    // 添加节点
    public Node insert(int no, Node t) {
        if (t == null) {
            return new Node(no);
        }

        int comResult = no - t.value;

        if (comResult < 0) {
            t.left = insert(no, t.left);
        }

        if (comResult > 0) {
            t.right = insert(no, t.right);
        }

        return balance(t);
    }

    public Node balance(Node t) {
        if (t == null) {
            return t;
        }

        // 左子树高度>右子树高度
        if (t.getLeftHeight() - t.getRightHeight() > 1) {
            if (t.left.getLeftHeight() >= t.left.getRightHeight()) {
                t = turnLeft(t);
            } else {
                t.left = turnRight(t.left);
                t = turnLeft(t);
            }
        }

        // 右子树高度>左子树高度
        if (t.getRightHeight() - t.getLeftHeight() > 1) {
            if (t.right.getRightHeight() >= t.right.getLeftHeight()) {
                t = turnRight(t);
            } else {
                t.right = turnRight(t.right);
                t = turnRight(t);
            }
        }

        return t;

    }

    // 左旋转:左子树高度-右子树高度>1时,将左边的子树向右旋转
    public Node turnLeft(Node t) {
        Node newroot = t.left;
        t.left = newroot.right;
        newroot.right = t;// 修改部分-----修改操作:添加此语句
        return newroot;
    }

    // 右旋转:右子树高度-左子树高度>1时,将右边的子树向左旋转
    public Node turnRight(Node t) {
        Node newroot = t.right;
        t.right = newroot.left;
        newroot.left = t;// 修改部分-----修改操作:添加此语句
        return newroot;
    }

    // 前序遍历
    public void preOrder() {
        System.out.println(this);
        if (this.left != null) {
            this.left.preOrder();
        }

        if (this.right != null) {
            this.right.preOrder();
        }
    }

}

运行结果:

 

平衡前的树:

 

平衡后:

 

posted @ 2021-03-29 17:36  L1998  阅读(37)  评论(0)    收藏  举报