优先队列——斜堆

【0】README

0.1)本文部分内容转自  http://www.cnblogs.com/skywang12345/p/3638493.html, 旨在理解 优先队列——斜堆 的基础知识
0.2) for original source code , please visit https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter6/p150_skew_heap


【1】优先队列——斜堆相关

1.0)斜堆定义: 斜堆是具有堆序性的二叉树, 与左式堆的差别在于没有零路径属性,故merge操作后,不需要考虑左右子堆的零路径大小,而是无条件交换左右子堆;(干货——斜堆定义)

1.1)定义:斜堆(Skew heap)也叫自适应堆(self-adjusting heap),它是左式堆的一个变种。和左式堆一样,它通常也用于实现优先队列。它的合并操作的时间复杂度也是O(log n)。
1.2)相比于左倾堆,斜堆的节点没有”零距离”这个属性: 除此之外,它们斜堆的合并操作也不同。
1.3)斜堆的合并操作算法如下:

  • case1) 如果一个空斜堆与一个非空斜堆合并,返回非空斜堆。
  • case2) 如果两个斜堆都非空,那么比较两个根节点,取较小堆的根节点为新的根节点。将”较小堆的根节点的右孩子”和”较大堆”进行合并。
  • case3) 合并后,交换新堆根节点的左孩子和右孩子。

Attention)

  • A1)第3步是斜堆和左式堆的合并操作差别的关键所在,如果是左式堆,则合并后要比较左右孩子的零距离大小,若右孩子的零距离 > 左孩子的零距离,则交换左右孩子;最后,在设置根的零距离。
  • A2) 下面是一个关于斜堆的干货荔枝:

【2】source code + printing results

2.1)source code at a glance

#include "skew_heap.h" 

// swap the left and the right in priority queue.
void swap(PriorityQueue h1)
{
    PriorityQueue temp;

    temp = h1->left;
    h1->left = h1->right;
    h1->right = temp;
}

// analog print directories and files name in the BinaryTree, which involves postorder traversal. 
void printPreorder(int depth, TreeNode root)
{           
    int i;

    if(root) 
    {      
        for(i = 0; i < depth; i++)
            printf("    ");     
        printf("%d\n", root->value);
        printPreorder(depth + 1, root->left); 
         // Attention: there's difference between traversing binary tree and common tree.
        printPreorder(depth + 1, root->right);
    }
    else 
    {
        for(i = 0; i < depth; i++)
            printf("    ");     
        printf("NULL\n");
    }
}

// insert an element with value into the priority queue.
PriorityQueue insert(ElementType value, PriorityQueue pq)
{
    TreeNode node;          

    node = (TreeNode)malloc(sizeof(struct TreeNode));
    if(!node)
    {
        Error("failed inserting, for out of space !");
        return pq;
    }
    node->left = NULL;
    node->right = NULL; 
    node->value = value;    

    if(pq == NULL) // means that just only creating a node with value.
    {
        return node;
    }
    else
    {
        return merge(node, pq);     
    }
}

// return the minimal between a and b.
int minimal(int a, int b)
{
    return a > b ? b : a;
}

// merge the priority queue h1 and h2.
PriorityQueue merge(PriorityQueue h1, PriorityQueue h2)
{       
    if(h1 == NULL)
    {
        return h2;
    }
    else if(h2 == NULL)
    {
        return h1;
    }   
    if(h1->value > h2->value)
    {
        return innerMerge(h2, h1);
    }
    else
    {
        return innerMerge(h1, h2);
    }   
}

// merge the priority queue h1 and h2.
PriorityQueue innerMerge(PriorityQueue h1, PriorityQueue h2)
{ 
    if(h1->left == NULL)
    {
        h1->left = h2;
    }
    else
    {
        h1->right = merge(h1->right, h2);
        swap(h1);       
    }       

    return h1;
} 

int main()
{
    PriorityQueue h1;
    PriorityQueue h2;   
    int data[] =  {21, 10, 23, 14, 3, 26, 17, 8};   
    int data2[] = {18, 7, 37, 6, 24, 33, 12, 18};   
    int i;

    h1 = insert(data[0], NULL);
    for(i=1; i<8; i++)
    {
        h1 = insert(data[i], h1);
    }
    printf("\n=== after the leftist heap h1 is merged===\n");
    printPreorder(1, h1);


    h2 = insert(data2[0], NULL);
    for(i=1; i<8; i++)
    {
        h2 = insert(data2[i], h2);
    }
    printf("\n=== after the leftist heap h2 is merged===\n");
    printPreorder(1, h2);

    h1 = merge(h1, h2);
    printf("\n=== after both h1 and h2 are merged===\n");
    printPreorder(1, h1);  

    return  0;
}

2.2) printing results

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值