日期:2014-05-20  浏览次数:20855 次

请教平衡二叉树(AVLtree)的 deleteMin() 操作算法
各位大哥,小弟最近在想用AVL树实现priority queue的算法(当然用heap更简单), 但是对于用AVL树实现deleteMin()的操作,依次删除最小元素,并返回其值,直到删除树的最后一个元素的算法实在想不出来。我知道这其实和插入操作类似,因为删除会破坏平衡,因此需要通过旋转来使树重新平衡,但和插入的过程很不一样,想了几天也没头绪。不知有没有高手可以指点一下,有算法可以分享一下就更好了?下面是我写了一半的程序,插入操作可以正常完成,deleteMin()就有问题了。非常感谢!:)

Java code

public class MyHeap implements PriorityQueue  {
       
       private AVLNode root;//declare the root node
        
       //Construct the AVL tree.
        public MyHeap(){
            root = null;
        }

       //Insert new item into the AVL tree.
        public void insert(double x){
            root = insert(x, root);
        }

        //Remove the minimum item from the tree and return its value.
        public double deleteMin(){    
           double temp=elementAt(findMin(root));
           deleteMin(root);
           return temp;
        }
        
        //Find and return the smallest item in the tree and return its value.
        public double findMin(){
            return elementAt(findMin(root));
        }

        /**
         * Check whether tree is empty or not 
         * return 1-->is empty 
         * return 0-->is not empty    
         */
        public boolean isEmpty(){
            return root == null;
        }

        // Erases all elements from the AVL tree.
        public void makeEmpty(){
            while(root!=null)
                deleteMin();
        }

       
        //return the element associate with node t
        private double elementAt(AVLNode t){
            return t == null ? null : t.element;
        }

        /**
         * Internal method to insert into a subtree.
         * @param x the item to insert.
         * @param t the node that roots the tree.
         * @return the new root.
         */
        private AVLNode insert(double x, AVLNode t ){
            if( t == null )
                return new AVLNode(x,null,null);
            
            if(x<t.element){
                t.left = insert(x, t.left);
                if(height(t.left)-height(t.right) == 2 )
                    if(x<t.left.element)
                        t = rotateLeft(t);
                    else
                        t = doubleRotateLeft(t);
            }
            
            else if(x>t.element){
                t.right = insert(x, t.right);
                if(height(t.right) - height(t.left) == 2)
                    if(x>t.right.element)
                        t = rotateRight(t);
                    else
                        t = doubleRotateRight(t);
            }
            
            else
                ;  // Duplicate; do nothing
            t.height = Math.max(height(t.left), height(t.right)) + 1;
            
            return t;
        }

        /**
         * private method to find the smallest item in the subtree.
         * @param t the node that roots the tree.
         */
        private AVLNode findMin(AVLNode t){
            if(t == null)
                return null;

            while(t.left != null)
                t = t.left;
            
            return t;
        }
        
        private AVLNode deleteMin(AVLNode t){
            if(t==null)
                throw new EmptyHeapException();
            else if(t.left!=null){
                t.left=deleteMin(t.left);
                if(height(t.right)-height(t.left) == 2 )
                    
                        t = rotateLeft(t);
                    else
                        t = doubleRotateLeft(t);
          
                return t;
            }
            else 
                return t.right;
        }


        //in-order traverse the AVL tree
        private void traverse(AVLNode t)
        {
            if( t != null )
            {
                traverse(t.left);
                System.out.println( t.element );
                traverse(t.right);
            }
        }

       
        //Return the height of node t, or -1, if null.
        private int height(AVLNode t){
            return t == null?-1:t.height;
        }

        
        /**
         * Rotate AVL tree node with left child.
         * this is a single rotation for case 1.
         * Update heights, then return new root.
         */
        private AVLNode rotateLeft(AVLNode root)
        {
            AVLNode temp = root.left;
            root.left = temp.right;
            temp.right = root;
            root.height = Math.max(height(root.right), height(root.left))+1;
            temp.height = Math.max(height(temp.right), height(temp.left))+1;
            root=temp;
            return root;
        }

        /**
         * Rotate AVL tree node with right child.
         * this is a single rotation for case 4.
         * Update heights, then return new root.
         */
        private AVLNode rotateRight(AVLNode root)
        {
            AVLNode temp = root.right;
            root.right = temp.left;
            temp.left = root;
            root.height = Math.max(height(root.right), height(root.left))+1;
            temp.height = Math.max(height(temp.right), height(temp.left))+1;
            root=temp;
            return root;
        }

        /**
         * Double rotate AVL tree node: first left child
         * with its right child; then root with new left child.
         * this is a double rotation for case 2.
         * Update heights, then return new root.
         */
        private AVLNode doubleRotateLeft(AVLNode root){
            root.left = rotateRight(root.left);
            return rotateLeft(root);
        }

        /**
         * Double rotate AVL tree node: first right child
         * with its left child; then root with new right child.
         * this is a double rotation for case 3.
         * Update heights, then return new root.
         */
        private AVLNode doubleRotateRight(AVLNode root){
            root.right = rotateLeft(root.right);
            return rotateRight(root);
        }
          
    }


/**
* AVLNode class used in MyHeap class
*@ Liyun Zeng
*@ 2-1-09
*/

class AVLNode{
    double element;   // The data include in the node
    AVLNode left;     // Left child reference
    AVLNode right;    // Right child reference
    int height;       // Height of this node
       
    // Constructors
    AVLNode(double theElement){
        this(theElement, null, null);
    }

    AVLNode(double theElement, AVLNode lt, AVLNode rt ){
        element  = theElement;
        left     = lt;
        right    = rt;
        height   = 0;
    }

}