• 斜堆(待补充)


    一、斜堆的介绍

    斜堆(Skew heap)也叫自适应堆(self-adjusting heap),它是左倾堆的一个变种。和左倾堆一样,它通常也用于实现优先队列;作为一种自适应的左倾堆,它的合并操作的时间复杂度也是O(lg n)。
    它与左倾堆的差别是:
    (01) 斜堆的节点没有"零距离"这个属性,而左倾堆则有。
    (02) 斜堆的合并操作和左倾堆的合并操作算法不同。

    斜堆的合并操作
    (01) 如果一个空斜堆与一个非空斜堆合并,返回非空斜堆。
    (02) 如果两个斜堆都非空,那么比较两个根节点,取较小堆的根节点为新的根节点。将"较小堆的根节点的右孩子"和"较大堆"进行合并。
    (03) 合并后,交换新堆根节点的左孩子和右孩子。
           第(03)步是斜堆和左倾堆的合并操作差别的关键所在,如果是左倾堆,则合并后要比较左右孩子的零距离大小,若右孩子的零距离 > 左孩子的零距离,则交换左右孩子;最后,在设置根的零距离。

    二、斜堆的基本操作

    1. 基本定义

    template <class T>
    class SkewNode{
        public:
            T key;                // 关键字(键值)
            SkewNode *left;        // 左孩子
            SkewNode *right;    // 右孩子
    
            SkewNode(T value, SkewNode *l, SkewNode *r):
                key(value), left(l),right(r) {}
    };

    SkewNode是斜堆对应的节点类。

    template <class T>
    class SkewHeap {
        private:
            SkewNode<T> *mRoot;    // 根结点
    
        public:
            SkewHeap();
            ~SkewHeap();
    
            // 前序遍历"斜堆"
            void preOrder();
            // 中序遍历"斜堆"
            void inOrder();
            // 后序遍历"斜堆"
            void postOrder();
    
             // 将other的斜堆合并到this中。
            void merge(SkewHeap<T>* other);
            // 将结点(key为节点键值)插入到斜堆中
            void insert(T key);
            // 删除结点(key为节点键值)
            void remove();
    
            // 销毁斜堆
            void destroy();
    
            // 打印斜堆
            void print();
        private:
    
            // 前序遍历"斜堆"
            void preOrder(SkewNode<T>* heap) const;
            // 中序遍历"斜堆"
            void inOrder(SkewNode<T>* heap) const;
            // 后序遍历"斜堆"
            void postOrder(SkewNode<T>* heap) const;
    
            // 交换节点x和节点y
            void swapNode(SkewNode<T> *&x, SkewNode<T> *&y);
            // 合并"斜堆x"和"斜堆y"
            SkewNode<T>* merge(SkewNode<T>* &x, SkewNode<T>* &y);
    
            // 销毁斜堆
            void destroy(SkewNode<T>* &heap);
    
            // 打印斜堆
            void print(SkewNode<T>* heap, T key, int direction);
    };

    SkewHeap是斜堆类,它包含了斜堆的根节点,以及斜堆的操作。

    2. 合并

    /*
     * 合并"斜堆x"和"斜堆y"
     */
    template <class T>
    SkewNode<T>* SkewHeap<T>::merge(SkewNode<T>* &x, SkewNode<T>* &y)
    {
        if(x == NULL)
            return y;
        if(y == NULL)
            return x;
    
        // 合并x和y时,将x作为合并后的树的根;
        // 这里的操作是保证: x的key < y的key
        if(x->key > y->key)
            swapNode(x, y);
    
        // 将x的右孩子和y合并,
        // 合并后直接交换x的左右孩子,而不需要像左倾堆一样考虑它们的npl。
        SkewNode<T> *tmp = merge(x->right, y);
        x->right = x->left;
        x->left  = tmp;
    
        return x;
    }
    
    /*
     * 将other的斜堆合并到this中。
     */
    template <class T>
    void SkewHeap<T>::merge(SkewHeap<T>* other)
    {
        mRoot = merge(mRoot, other->mRoot);
    }

    merge(x, y)是内部接口,作用是合并x和y这两个斜堆,并返回得到的新堆的根节点。
    merge(other)是外部接口,作用是将other合并到当前堆中。

    3. 添加

    /* 
     * 新建键值为key的结点并将其插入到斜堆中
     *
     * 参数说明:
     *     heap 斜堆的根结点
     *     key 插入的结点的键值
     * 返回值:
     *     根节点
     */
    template <class T>
    void SkewHeap<T>::insert(T key)
    {
        SkewNode<T> *node;    // 新建结点
    
        // 新建节点
        node = new SkewNode<T>(key, NULL, NULL);
        if (node==NULL)
        {
            cout << "ERROR: create node failed!" << endl;
            return ;
        }
    
        mRoot = merge(mRoot, node);
    }

    insert(key)的作用是新建键值为key的节点,并将其加入到当前斜堆中。

    4. 删除

    /* 
     * 删除结点
     */
    template <class T>
    void SkewHeap<T>::remove()
    {
        if (mRoot == NULL)
            return NULL;
    
        SkewNode<T> *l = mRoot->left;
        SkewNode<T> *r = mRoot->right;
    
        // 删除根节点
        delete mRoot;
        // 左右子树合并后的新树
        mRoot = merge(l, r); 
    }

    remove()的作用是删除斜堆的最小节点。

    本文来自http://www.cnblogs.com/skywang12345/p/3638524.html#a1

  • 相关阅读:
    wordpress 的主题
    yapi api协作管理平台
    美团外卖券小程序路径过长导致插入文本消息失败的问题解决办法
    mp://XzDiXafjfvLnjvp
    supervisor 命令
    YII beego gin 框架对比
    芝麻微客-企业微信公域到私域流量运营助手
    H5跳转小程序
    PowerBI开发 第十九篇:基于Page创建Tooltip
    PowerBI开发 第十八篇:行级安全(RLS)
  • 原文地址:https://www.cnblogs.com/msymm/p/9757526.html
Copyright © 2020-2023  润新知