二项队列(类结构及节点定义)

二项队列的构造函数和常用操作:


    /**
     * Implements a binomial queue.(实现二项队列)
     * Note that all "matching" is based on the compareTo method.
     * (节点的匹配借助compareTo方法)
     */  
    public class BinomialQueue
    {
        public BinomialQueue( ) //Construct the binomial queue.
        {
            theTrees = new BinomialNode[ MAX_TREES ];
            makeEmpty( );
         }

        /**
         * Merge rhs into the priority queue.
         * rhs becomes empty. rhs must be different from this.
         * @param rhs the other binomial queue.
         * @exception Overflow if result exceeds capacity.
         */
        public void merge( BinomialQueue rhs ) throws Overflow
        {
             if( this == rhs )    // Avoid aliasing problems
                return;
             if( currentSize + rhs.currentSize > capacity( ) )
                throw new Overflow( );

            currentSize += rhs.currentSize;

            BinomialNode carry = null;
            for( int i = 0, j = 1; j <= currentSize; i++, j *= 2 )
            {

                BinomialNode t1 = theTrees[ i ];
                BinomialNode t2 = rhs.theTrees[ i ];

                int whichCase = t1 == null ? 0 : 1;
                whichCase += t2 == null ? 0 : 2;
                whichCase += carry == null ? 0 : 4;

                switch( whichCase )
                {

                  case 0: /* No trees */
                  case 1: /* Only this */
                    break;
                  case 2: /* Only rhs */
                    theTrees[ i ] = t2;
                    rhs.theTrees[ i ] = null;
                    break;
                  case 4: /* Only carry */
                    theTrees[ i ] = carry;
                    carry = null;
                    break;
                  case 3: /* this and rhs */
                    carry = combineTrees( t1, t2 );
                    theTrees[ i ] = rhs.theTrees[ i ] = null;
                    break;
                  case 5: /* this and carry */
                    carry = combineTrees( t1, carry );
                    theTrees[ i ] = null;
                    break;
                  case 6: /* rhs and carry */
                    carry = combineTrees( t2, carry );
                    rhs.theTrees[ i ] = null;
                    break;
                  case 7: /* All three */
                    theTrees[ i ] = carry;
                    carry = combineTrees( t1, t2 );
                    rhs.theTrees[ i ] = null;
                    break;
                 }
            }
            for( int k = 0; k < rhs.theTrees.length; k++ )
                rhs.theTrees[ k ] = null;
            rhs.currentSize = 0;
}        

        /**
         * Return the result of merging equal-sized t1 and t2.
         */
        private static BinomialNode combineTrees( BinomialNode t1,
                                                  BinomialNode t2 )
        {

            if( t1.element.compareTo( t2.element ) > 0 )
                return combineTrees( t2, t1 );
            t2.nextSibling = t1.leftChild;
            t1.leftChild = t2;
            return t1;

}

        /**
         * Insert into the priority queue, maintaining heap order.
         * This implementation is not optimized for O(1) performance.
         * @param x the item to insert.
         * @exception Overflow if capacity exceeded.
         */
        public void insert( Comparable x ) throws Overflow
        {

            BinomialQueue oneItem = new BinomialQueue( );
            oneItem.currentSize = 1;
            oneItem.theTrees[ 0 ] = new BinomialNode( x );

            merge( oneItem );

}

        /**
         * Find the smallest item in the priority queue.
         * @return the smallest item, or null, if empty.
         */
        public Comparable findMin( )
        {

            if( isEmpty( ) )
                return null;

            return theTrees[ findMinIndex( ) ].element;

}


        /**
         * Find index of tree containing the smallest item in the priority queue.
         * The priority queue must not be empty.
         * @return the index of tree containing the smallest item.
         */
        private int findMinIndex( )
        {

            int i;
            int minIndex;

            for( i = 0; theTrees[ i ] == null; i++ )
                ;

            for( minIndex = i; i < theTrees.length; i++ )
                if( theTrees[ i ] != null &&
                    theTrees[ i ].element.compareTo( theTrees[ minIndex ].element ) < 0 )
                    minIndex = i;

            return minIndex;

}

        /**
         * Remove the smallest item from the priority queue.
         * @return the smallest item, or null, if empty.
         */
        public Comparable deleteMin( )
        {

            if( isEmpty( ) )
                return null;

            int minIndex = findMinIndex( );
            Comparable minItem = theTrees[ minIndex ].element;

            BinomialNode deletedTree = theTrees[ minIndex ].leftChild;

            BinomialQueue deletedQueue = new BinomialQueue( );
            deletedQueue.currentSize = ( 1 << minIndex ) - 1;
            for( int j = minIndex - 1; j >= 0; j-- )
            {

                deletedQueue.theTrees[ j ] = deletedTree;
                deletedTree = deletedTree.nextSibling;
                deletedQueue.theTrees[ j ].nextSibling = null;

}

            theTrees[ minIndex ] = null;
            currentSize -= deletedQueue.currentSize + 1;

            try
              {
 merge( deletedQueue ); 
}
            catch( Overflow e ) {

}
            return minItem;

}

        /**
         * Test if the priority queue is logically empty.
         * @return true if empty, false otherwise.
         */
        public boolean isEmpty( )
        {

            return currentSize == 0;

}

        /**
         * Test if the priority queue is logically full.
         * @return true if full, false otherwise.
         */
        public boolean isFull( )
        {

            return currentSize == capacity( );

}

        /**
         * Make the priority queue logically empty.
         */
        public void makeEmpty( )
        {

            currentSize = 0;
            for( int i = 0; i < theTrees.length; i++ )
                theTrees[ i ] = null;

}


        private static final int MAX_TREES = 14;

        private int currentSize;            // # items in priority queue
        private BinomialNode [ ] theTrees;  // An array of tree roots


        /**
         * Return the capacity.
         */
        private int capacity( )
        {

            return ( 1 << theTrees.length ) - 1;

}

        public static void main( String [ ] args )
        {

            int numItems = 10000;
            BinomialQueue h  = new BinomialQueue( );
            BinomialQueue h1 = new BinomialQueue( );
            int i = 37;

            System.out.println( "Starting check." );
            try
            {

                for( i = 37; i != 0; i = ( i + 37 ) % numItems )
                    if( i % 2 == 0 )
                        h1.insert( new MyInteger( i ) );
                    else
                        h.insert( new MyInteger( i ) );

                h.merge( h1 );
                for( i = 1; i < numItems; i++ )
                    if( ((MyInteger)( h.deleteMin( ) )).intValue( ) != i )
                        System.out.println( "Oops! " + i );

}
            catch( Overflow e ) {
 System.out.println( "Unexpected overflow" ); 
} 
            System.out.println( "Check done." );

}

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值