左式堆的合并

Posted iamzhoug37

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了左式堆的合并相关的知识,希望对你有一定的参考价值。

package heap;

import java.util.Stack;

public class LeftHeap
{
    int num ;
    LeftHeap left ;
    LeftHeap right ;
    int npl ;

    public LeftHeap() {}

    public LeftHeap(int num, int npl) {
        this.npl = npl;
        this.num = num;
    }

    /**
     * 左式堆合并的非递归实现
     */
    public static LeftHeap merge_unrec(LeftHeap h1 , LeftHeap h2)
    {
        if(h1 == null || h2 == null)
            return h1 == null ? h2 : h1 ;

        Stack<LeftHeap> stack = new Stack<>() ; //用于保存每一级的父节点

        while (h2 != null || !stack.isEmpty())
        {
            if(h1 != null && h2 != null)
            {
                if(h1.num > h2.num) //确保h1为小值的堆,h2为大值的堆
                {
                    LeftHeap temp = h1 ;
                    h1 = h2 ;
                    h2 = temp ;
                }

                if(h1.left == null) //当小堆的左子树为空时, 直接将h2作为他的左子树即可, 由于仍不存在右子树, 所以npl无需更新
                {
                    h1.left = h2 ;
                    h2 = null ;
                }
                else
                {
                    stack.push(h1) ;    //说明左右子树都存在, 此时应将h1保存, 让h1的右子树和h2进行合并
                    h1 = h1.right ;
                }
            }
            else  //各级的父节点连接右子树
            {
                if(h1 == null)
                {
                    h1 = h2 ;
                    h2 = null ;
                }
                while (!stack.isEmpty())
                {
                    LeftHeap heap = stack.pop() ;
                    heap.right = h1 ;
                    if(heap.left.npl < heap.right.npl)
                        swapLR(heap) ;
                    heap.npl = heap.right.npl+1 ;
                    h1 = heap ;
                }
            }
        }
        return h1 ;
    }

    public static LeftHeap merge(LeftHeap h1 , LeftHeap h2)
    {
        if(h1 == null || h2 == null)
            return h1 == null ? h2 : h1 ;
        if(h1.num > h2.num)
            return merge1(h2 , h1) ;
        else
            return merge1(h1 , h2) ;
    }

    private static LeftHeap merge1(LeftHeap h1 , LeftHeap h2)
    {
        if(h1.left == null)
            h1.left = h2 ;
        else
        {
            h1.right = merge(h1.right , h2) ;
            if(h1.left.npl < h1.right.npl)
                swapLR(h1) ;
            h1.npl = h1.right.npl+1 ;
        }

        return h1 ;
    }

    private static void swapLR(LeftHeap h)
    {
        LeftHeap temp = h.left ;
        h.left = h.right ;
        h.right = temp ;
    }

    public static void inOrder(LeftHeap heap)
    {
        if(heap == null)
            return ;
        inOrder(heap.left);
        System.out.print(heap.num + " ");
        inOrder(heap.right);
    }
    public static void main(String[] args)
    {
        LeftHeap h1 = new LeftHeap(3, 1) ;
        LeftHeap h2 = new LeftHeap(10, 1) ;
        LeftHeap h3 = new LeftHeap(8, 0) ;
        LeftHeap h4 = new LeftHeap(21, 0) ;
        LeftHeap h5 = new LeftHeap(14, 0) ;
        LeftHeap h6 = new LeftHeap(17, 0) ;
        LeftHeap h7 = new LeftHeap(23, 0) ;
        LeftHeap h8 = new LeftHeap(26, 0) ;

        h1.left = h2 ;
        h1.right = h3 ;
        h2.left = h4 ;
        h2.right = h5 ;
        h3.left = h6 ;
        h5.left = h7 ;
        h6.left = h8 ;

        LeftHeap a = h1 ;

        h1 = new LeftHeap(6,2) ;
        h2 = new LeftHeap(12,1) ;
        h3 = new LeftHeap(7,1) ;
        h4 = new LeftHeap(18,0) ;
        h5 = new LeftHeap(24,0) ;
        h6 = new LeftHeap(37,0) ;
        h7 = new LeftHeap(18,0) ;
        h8 = new LeftHeap(33,0) ;

        h1.left = h2 ;
        h1.right = h3 ;
        h2.left = h4 ;
        h2.right = h5 ;
        h3.left = h6 ;
        h3.right = h7 ;
        h5.left = h8 ;

        LeftHeap b = h1 ;

        LeftHeap heap = merge_unrec(a , b) ;

        inOrder(heap) ;

    }
}

左式堆合并的时间复杂度为O(N) , 由于n个节点的左式堆的右子树最多含有log(N+1)个节点, 而且每次合并都是与较小值堆的右子树进行比较, 所以为O(N)

以上是关于左式堆的合并的主要内容,如果未能解决你的问题,请参考以下文章

数据结构--左式堆的思想和代码

堆之左式堆和斜堆

左式堆的实现与详解

左式堆

转载:数据结构 左式堆

左式堆