AVL樹----java,avl----java

來源:互聯網
上載者:User

AVL樹----java,avl----java

                                                                                    AVL樹----java

AVL樹是高度平衡的二叉尋找樹

1.單旋轉LL旋轉


理解記憶:1.在不平衡的節點的左孩子的左孩子插入導致的不平衡,所以叫LL

private AVLTreeNode<T> leftLeftRotation(AVLTreeNode<T> k2) {    AVLTreeNode<T> k1;    k1 = k2.left;    k2.left = k1.right;    k1.right = k2;    k2.height = max( height(k2.left), height(k2.right)) + 1;    k1.height = max( height(k1.left), k2.height) + 1;    return k1;}

2.單旋轉RR


理解記憶:1.不平衡節點的右孩子的有孩子插入導致的不平衡,所以叫RR

private AVLTreeNode<T> rightRightRotation(AVLTreeNode<T> k1) {    AVLTreeNode<T> k2;    k2 = k1.right;    k1.right = k2.left;    k2.left = k1;    k1.height = max( height(k1.left), height(k1.right)) + 1;    k2.height = max( height(k2.right), k1.height) + 1;    return k2;}
3.雙旋轉LR

理解記憶:1.不平衡節點的左孩子的有孩子導致的不平衡,所以叫LR

                     2.需要先對k1  RR,再對根K3  LL

private AVLTreeNode<T> leftRightRotation(AVLTreeNode<T> k3) {    k3.left = rightRightRotation(k3.left);    return leftLeftRotation(k3);}
4.雙旋轉RL


理解記憶:1.不平衡節點的右孩子的左孩子導致的不平衡,所以叫RL

                     2.需要先對k3 LL,在對k1 RR

private AVLTreeNode<T> rightLeftRotation(AVLTreeNode<T> k1) {    k1.right = leftLeftRotation(k1.right);    return rightRightRotation(k1);}
5.AVL的例子

遍曆,尋找等和二叉尋找樹一樣就不在列出,主要是 插入 和 刪除

public class AVLTree<T extends Comparable<T>> {    private AVLTreeNode<T> mRoot;    // 根結點    // AVL樹的節點(內部類)    class AVLTreeNode<T extends Comparable<T>> {        T key;                // 關鍵字(索引值)        int height;         // 高度        AVLTreeNode<T> left;    // 左孩子        AVLTreeNode<T> right;    // 右孩子        public AVLTreeNode(T key, AVLTreeNode<T> left, AVLTreeNode<T> right) {            this.key = key;            this.left = left;            this.right = right;            this.height = 0;        }    }    // 建構函式    public AVLTree() {        mRoot = null;    }    /*     * 擷取樹的高度     */    private int height(AVLTreeNode<T> tree) {        if (tree != null)            return tree.height;        return 0;    }    public int height() {        return height(mRoot);    }    /*     * 比較兩個值的大小     */    private int max(int a, int b) {        return a>b ? a : b;    }    /*     * 前序走訪"AVL樹"     */    private void preOrder(AVLTreeNode<T> tree) {        if(tree != null) {            System.out.print(tree.key+" ");            preOrder(tree.left);            preOrder(tree.right);        }    }    public void preOrder() {        preOrder(mRoot);    }    /*     * 中序遍曆"AVL樹"     */    private void inOrder(AVLTreeNode<T> tree) {        if(tree != null)        {            inOrder(tree.left);            System.out.print(tree.key+" ");            inOrder(tree.right);        }    }    public void inOrder() {        inOrder(mRoot);    }    /*     * 後序遍曆"AVL樹"     */    private void postOrder(AVLTreeNode<T> tree) {        if(tree != null) {            postOrder(tree.left);            postOrder(tree.right);            System.out.print(tree.key+" ");        }    }    public void postOrder() {        postOrder(mRoot);    }    /*     * (遞迴實現)尋找"AVL樹x"中索引值為key的節點     */    private AVLTreeNode<T> search(AVLTreeNode<T> x, T key) {        if (x==null)            return x;        int cmp = key.compareTo(x.key);        if (cmp < 0)            return search(x.left, key);        else if (cmp > 0)            return search(x.right, key);        else            return x;    }    public AVLTreeNode<T> search(T key) {        return search(mRoot, key);    }    /*     * (非遞迴實現)尋找"AVL樹x"中索引值為key的節點     */    private AVLTreeNode<T> iterativeSearch(AVLTreeNode<T> x, T key) {        while (x!=null) {            int cmp = key.compareTo(x.key);            if (cmp < 0)                x = x.left;            else if (cmp > 0)                x = x.right;            else                return x;        }        return x;    }    public AVLTreeNode<T> iterativeSearch(T key) {        return iterativeSearch(mRoot, key);    }    /*      * 尋找最小結點:返回tree為根結點的AVL樹的最小結點。     */    private AVLTreeNode<T> minimum(AVLTreeNode<T> tree) {        if (tree == null)            return null;        while(tree.left != null)            tree = tree.left;        return tree;    }    public T minimum() {        AVLTreeNode<T> p = minimum(mRoot);        if (p != null)            return p.key;        return null;    }         /*      * 尋找最大結點:返回tree為根結點的AVL樹的最大結點。     */    private AVLTreeNode<T> maximum(AVLTreeNode<T> tree) {        if (tree == null)            return null;        while(tree.right != null)            tree = tree.right;        return tree;    }    public T maximum() {        AVLTreeNode<T> p = maximum(mRoot);        if (p != null)            return p.key;        return null;    }    /*     * LL:左左對應的情況(左單旋轉)。     *     * 傳回值:旋轉後的根節點     */    private AVLTreeNode<T> leftLeftRotation(AVLTreeNode<T> k2) {        AVLTreeNode<T> k1;        k1 = k2.left;        k2.left = k1.right;        k1.right = k2;        k2.height = max( height(k2.left), height(k2.right)) + 1;        k1.height = max( height(k1.left), k2.height) + 1;        return k1;    }    /*     * RR:右右對應的情況(右單旋轉)。     *     * 傳回值:旋轉後的根節點     */    private AVLTreeNode<T> rightRightRotation(AVLTreeNode<T> k1) {        AVLTreeNode<T> k2;        k2 = k1.right;        k1.right = k2.left;        k2.left = k1;        k1.height = max( height(k1.left), height(k1.right)) + 1;        k2.height = max( height(k2.right), k1.height) + 1;        return k2;    }    /*     * LR:左右對應的情況(左雙旋轉)。     *     * 傳回值:旋轉後的根節點     */    private AVLTreeNode<T> leftRightRotation(AVLTreeNode<T> k3) {        k3.left = rightRightRotation(k3.left);        return leftLeftRotation(k3);    }    /*     * RL:右左對應的情況(右雙旋轉)。     *     * 傳回值:旋轉後的根節點     */    private AVLTreeNode<T> rightLeftRotation(AVLTreeNode<T> k1) {        k1.right = leftLeftRotation(k1.right);        return rightRightRotation(k1);    }    /*      * 將結點插入到AVL樹中,並返回根節點     *     * 參數說明:     *     tree AVL樹的根結點     *     key 插入的結點的索引值     * 傳回值:     *     根節點     */    private AVLTreeNode<T> insert(AVLTreeNode<T> tree, T key) {        if (tree == null) {            // 建立節點            tree = new AVLTreeNode<T>(key, null, null);            if (tree==null) {                System.out.println("ERROR: create avltree node failed!");                return null;            }        } else {            int cmp = key.compareTo(tree.key);               if (cmp < 0) {    // 應該將key插入到"tree的左子樹"的情況                tree.left = insert(tree.left, key);                // 插入節點後,若AVL樹失去平衡,則進行相應的調節。                if (height(tree.left) - height(tree.right) == 2) {                    if (key.compareTo(tree.left.key) < 0)                        tree = leftLeftRotation(tree);                    else                        tree = leftRightRotation(tree);                }            } else if (cmp > 0) {    // 應該將key插入到"tree的右子樹"的情況                tree.right = insert(tree.right, key);                // 插入節點後,若AVL樹失去平衡,則進行相應的調節。                if (height(tree.right) - height(tree.left) == 2) {                    if (key.compareTo(tree.right.key) > 0)                        tree = rightRightRotation(tree);                    else                        tree = rightLeftRotation(tree);                }            } else {    // cmp==0                System.out.println("添加失敗:不允許添加相同的節點!");            }        }        tree.height = max( height(tree.left), height(tree.right)) + 1;        return tree;    }    public void insert(T key) {        mRoot = insert(mRoot, key);    }    /*      * 刪除結點(z),返回根節點     *     * 參數說明:     *     tree AVL樹的根結點     *     z 待刪除的結點     * 傳回值:     *     根節點     */    private AVLTreeNode<T> remove(AVLTreeNode<T> tree, AVLTreeNode<T> z) {        // 根為空白 或者 沒有要刪除的節點,直接返回null。        if (tree==null || z==null)            return null;        int cmp = z.key.compareTo(tree.key);        if (cmp < 0) {        // 待刪除的節點在"tree的左子樹"中            tree.left = remove(tree.left, z);            // 刪除節點後,若AVL樹失去平衡,則進行相應的調節。            if (height(tree.right) - height(tree.left) == 2) {                AVLTreeNode<T> r =  tree.right;                if (height(r.left) > height(r.right))                    tree = rightLeftRotation(tree);                else                    tree = rightRightRotation(tree);            }        } else if (cmp > 0) {    // 待刪除的節點在"tree的右子樹"中            tree.right = remove(tree.right, z);            // 刪除節點後,若AVL樹失去平衡,則進行相應的調節。            if (height(tree.left) - height(tree.right) == 2) {                AVLTreeNode<T> l =  tree.left;                if (height(l.right) > height(l.left))                    tree = leftRightRotation(tree);                else                    tree = leftLeftRotation(tree);            }        } else {    // tree是對應要刪除的節點。            // tree的左右孩子都非空            if ((tree.left!=null) && (tree.right!=null)) {                if (height(tree.left) > height(tree.right)) {                    // 如果tree的左子樹比右子樹高;                    // 則(01)找出tree的左子樹中的最大節點                    //   (02)將該最大節點的值賦值給tree。                    //   (03)刪除該最大節點。                    // 這類似於用"tree的左子樹中最大節點"做"tree"的替身;                    // 採用這種方式的好處是:刪除"tree的左子樹中最大節點"之後,AVL樹仍然是平衡的。                    AVLTreeNode<T> max = maximum(tree.left);                    tree.key = max.key;                    tree.left = remove(tree.left, max);                } else {                    // 如果tree的左子樹不比右子樹高(即它們相等,或右子樹比左子樹高1)                    // 則(01)找出tree的右子樹中的最小節點                    //   (02)將該最小節點的值賦值給tree。                    //   (03)刪除該最小節點。                    // 這類似於用"tree的右子樹中最小節點"做"tree"的替身;                    // 採用這種方式的好處是:刪除"tree的右子樹中最小節點"之後,AVL樹仍然是平衡的。                    AVLTreeNode<T> min = maximum(tree.right);                    tree.key = min.key;                    tree.right = remove(tree.right, min);                }            } else {                AVLTreeNode<T> tmp = tree;                tree = (tree.left!=null) ? tree.left : tree.right;                tmp = null;            }        }        return tree;    }    public void remove(T key) {        AVLTreeNode<T> z;         if ((z = search(mRoot, key)) != null)            mRoot = remove(mRoot, z);    }    /*      * 銷毀AVL樹     */    private void destroy(AVLTreeNode<T> tree) {        if (tree==null)            return ;        if (tree.left != null)            destroy(tree.left);        if (tree.right != null)            destroy(tree.right);        tree = null;    }    public void destroy() {        destroy(mRoot);    }    /*     * 列印"二叉尋找樹"     *     * key        -- 節點的索引值      * direction  --  0,表示該節點是根節點;     *               -1,表示該節點是它的父結點的左孩子;     *                1,表示該節點是它的父結點的右孩子。     */    private void print(AVLTreeNode<T> tree, T key, int direction) {        if(tree != null) {            if(direction==0)    // tree是根節點                System.out.printf("%2d is root\n", tree.key, key);            else                // tree是分支節點                System.out.printf("%2d is %2d's %6s child\n", tree.key, key, direction==1?"right" : "left");            print(tree.left, tree.key, -1);            print(tree.right,tree.key,  1);        }    }    public void print() {        if (mRoot != null)            print(mRoot, mRoot.key, 0);    }}

文章大量參考:http://www.cnblogs.com/skywang12345/p/3577479.html



AVL樹所有的java遞迴演算法

www.doc88.com/p-292361550358.html
 
我有JAVA基礎可以參加海同科技的Java培訓

選擇匯才同飛教育JAVA快車培訓的理由:
  一、實在:java培訓小班授課每班最多25人,每人一台專用電腦,每周學習六天。
  二、實用:java培訓專職老師專業、敬業,具備三年以上一線開發經驗,java培訓課程的每個階段都會安排相關JAVA培訓項目練習,java培訓學習過程中積累實踐工作經驗。
  三、實惠:java培訓收費相當優惠,報JAVA班贈安卓培訓課程。以JAVA就業工資水平為口碑,是性價比最高的JAVA培訓機構。
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.