优先队列——左式堆

【0】README

0.1) 本文文字描述部分转自 数据结构与算法分析, 旨在理解 优先队列——左式堆 的基础知识;
0.2) 本文核心思路均为原创, 源代码部分借鉴 数据结构与算法分析 ;
0.3) for original source code, please visit https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter6/p145_leftist_heap

1)相关定义

  • 1.1)零路径长度定义: 到没有两个儿子的节点最短距离, 即零路径长Npl 定义为 从 X 到一个没有两个儿子的 节点的最短路径的长;也即, 非叶子节点到叶子节点的最少边数,其中NULL的零路径长为-1, 叶子节点的零路径长为0;(干货——零路径长的定义—— 非叶子节点到叶子节点或只有一个儿子的节点的最少边数,非常重要,因为左式堆的定义是基于零路径长的定义的)
    这里写图片描述

  • 1.2)左式堆定义:一棵具有堆序性质的二叉树 + 零路径长:左儿子 ≧ 右儿子 + 父节点 = min{儿子} +1;(干货——左式堆的定义是建立在具有堆序性的二叉树上,而不是二叉堆上)

2)merge操作原则: 根值大的堆与根值小的堆的右子堆合并;(干货——merge操作原则)
3)merge操作存在的三种情况(设堆H1的根值小于H2)

  • case1) H1只有一个节点;
  • case2) H1根无右孩子;
  • case3) H1根有右孩子;

补充(Complementary):左式堆合并操作详解(merge)

左式堆合并原则:大根堆H2与小根堆H1的右子堆合并 (干货——左式堆合并原则)
具体分三种情况(设堆H1的根值小于H2)
这里写图片描述

  • case1)H1只有一个节点(只有它自己而已): H1只有一个节点,若出现不满足 零路径长:左儿子≧右儿子,交换左右孩子;
    这里写图片描述
    • Attention)上例中(中间所示堆),左儿子的零路径长为-1, 而右儿子的零路径长为0,所以不满足左式堆的条件, 需要交换左右孩子;
  • case2)H1根无右孩子: H1根无右孩子,若出现不满足:零路径长:左儿子≧右儿子,需要交换左右孩子。
    这里写图片描述
    • Attention)上例中(中间所示堆),左儿子的零路径长为0, 而右儿子的零路径长为1,所以不满足左式堆的条件,需要交换;
  • case3)H1根有右孩子:
    • step1)截取H1的右子堆R1, 和截取H2的右子堆R2;
    • step2)将R1 与 R2进行merge操作得到H3, 且取R1和R2中较小根作为新根; (Attention: 现在你将看到,截取后的H1 和 H2, 以及新生成的H3 都是 case2);
    • step3)比较H3的左右孩子,是否满足左式堆要求,如果不满足则交换左右孩子;
    • step4)将H3与没有右子堆的H1进行merge操作,也即最后将case3 转换为了 case2;
      这里写图片描述
      这里写图片描述

Conclusion) 现在才知道,左式堆的merge操作其实是一个递归的过程, 看如下解析; (干货——这是最后解析merge操作啦)

Attention once again)

  • A1)左式堆是建立在具有堆序性的二叉树上;
  • A2)左式堆是建立在零路径长上;
  • A3)左式堆的核心操作是 merge, 无论insert 还是 deleteMin 都是基于 merge操作的;
  • A4)左式堆的merge操作执行后,还要update 左式堆根节点的零路径长, 左式堆根节点的零路径长 == min{儿子的零路径长} +1;
  • A5) update 后, 还需要比较 左右零路径长 是否满足左式堆的定义, 如果不满足,还需要交换左式堆根节点的左右孩子;



source code at a glance)

#include "leftist_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->nullPathLen = 0;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);}   // update the null path lengthif(h1->right == NULL){h1->nullPathLen = 0;}else{h1->nullPathLen = minimal(h1->left->nullPathLen, h1->right->nullPathLen) + 1;   // exchange the left and the rightif(h1->left->nullPathLen < h1->right->nullPathLen){swap(h1);}}return h1;
}// delete the minimal element in the priority queue.
PriorityQueue deleteMin(PriorityQueue h1)
{PriorityQueue left;PriorityQueue right;if(!h1){Error("failed deleteMin, for the root doesn't point to any position!");return NULL;}left = h1->left;right = h1->right;free(h1);return merge(left, right);
}int main()
{PriorityQueue h1;PriorityQueue h2;   int data[] =  {21, 10, 23, 14, 3, 26, 17, 8};   int data2[] = {18, 12, 33, 24, 6, 37, 7, 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);h1 = deleteMin(h1);printf("\n=== after executing deleteMin operation ===\n");printPreorder(1, h1);return  0;
}



printing results are as follows)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/331589.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Class类中的getEnclosing*、getDeclared*与getDeclaringClass的区别

一、getEnclosing* 当前类在……中闭合Class<?>getEnclosingClass() 返回底层类的立即封闭类。 Constructor<?>getEnclosingConstructor() 如果该 Class 对象表示构造方法中的一个本地或匿名类&#xff0c;则返回 Constructor 对象&#xf…

java联接pg库_Java14:使用Java 14的新记录联接数据库表

java联接pg库您是否知道可以使用Java 14的预览记录功能将数据库表连接到Java Stream中&#xff1f; 阅读这篇简短的文章&#xff0c;并了解如何使用Speedment Stream ORM完成它。 我们将从如何设置您的项目开始。 建立 下载Java 14 。 转到Speedment Initializer并下载您的项目…

html5遍历集合数据,HTMLCollection集合能打印出来值,但是无法获取每一个值。

var imgs $("#pictureQueryTable img").prevObject[0].images;下图是上面这句打印出来的结果&#xff1a;console.log可以打印出来该集合的数据&#xff0c;但是无法获取该集合中的每一个值&#xff0c;打印该集合的length为0&#xff0c;所以也无法遍历该集合进行操…

优先队列——斜堆

【0】README 0.1&#xff09;本文部分内容转自  http://www.cnblogs.com/skywang12345/p/3638493.html&#xff0c; 旨在理解 优先队列——斜堆 的基础知识&#xff1b; 0.2&#xff09; for original source code , please visit https://github.com/pacosonTang/dataStruc…

Class的getResource与ClassLoader的getResource路径/问题

一、Class的getResource(String path)&#xff1a;URL 1、path 不以’/开头时&#xff0c;默认是从此类所在的包下取资源&#xff1b; 2、path 以’/开头时&#xff0c;则是从ClassPath根下获取&#xff1b; System.out.println(Test.class.getResource("")); Syste…

java 轻量级文件数据库_Java:如何创建轻量级数据库微服务

java 轻量级文件数据库基于云的Java数据库应用程序的数量每分钟都在增加。 许多组织部署了数百甚至数千个微服务实例。 但是&#xff0c;相对于运行时环境&#xff0c;大多数应用程序会带来惊人的不必要开销。 反过来&#xff0c;这会使应用程序运行更慢&#xff0c;运行成本更…

html中显示shell脚本的输出,网页从shell脚本中输入并显示结果

首先&#xff0c;不是在BASH脚本中使用$USERNAME。 $USERNAME是一个包含当前用户名的BASH变量。实际上&#xff0c;在BASH中使用UPPERCASE变量通常是一个糟糕的主意。大多数BASH环境变量都是大写字母&#xff0c;可能会导致混淆。让你的变量小写是个好习惯。此外&#xff0c;因…

优先队列——二项队列(binominal queue)

【0】README 0.1&#xff09; 本文文字描述部分转自 数据结构与算法分析&#xff0c; 旨在理解 优先队列——二项队列&#xff08;binominal queue&#xff09; 的基础知识&#xff1b; 0.2&#xff09; 本文核心的剖析思路均为原创&#xff08;insert&#xff0c;merge和del…

Class的getName、getSimpleName与getCanonicalName的区别

一、getName 除了数组外&#xff0c;其他的类都是输出类全名以 String 的形式返回此 Class 对象所表示的实体&#xff08;类、接口、数组类、基本类型或 void&#xff09;名称。 1、此类对象表示的是非数组类型的引用类型&#xff0c; 返回该类的二进制名称&#xff0c;Java…

apache.camel_Apache Camel 3.1 –即将推出更多骆驼核心优化

apache.camel希望一切都很好&#xff0c;您可以安全进入2020年。 Camel团队已经在忙于开发下一个Camel 3.1版本。 目标之一是继续优化骆驼核心&#xff0c;这一次我们花了一些时间来寻找路由引擎中的一些热点。 我们所研究的方面之一也是在Camel路由的每个消息中发生的对象分…

xp系统的计算机管理中用户在哪里,WINDOWSXP的用户管理和系统安全设置

台计算机)⑤回到“添加独立管理单元”对话框&#xff0c;单击“关闭”&#xff0c;回到““控制台->添加/删除管理单元”对话框&#xff0c;再单击“确定”&#xff1b;⑥此时&#xff0c;在控制台窗口左窗格中看到新添加的控制单元“本地计算机策略”&#xff1b;⑦依次展开…

XML——StAX Streaming API for XML(read+write)

【0】README 0.1&#xff09; reshipping from http://www.journaldev.com/1191/how-to-read-xml-file-in-java-using-java-stax-api http://www.journaldev.com/892/how-to-write-xml-file-in-java-using-java-stax-api 0.2&#xff09; for all source code , please visi…

Class的getInterfaces与getGenericInterface区别

一、getInterfaces 返回直接实现的接口&#xff08; 由于编译擦除&#xff0c;没有显示泛型参数&#xff09; Class<?>[] getInterfaces() 确定此对象所表示的类或接口实现的接口。 确定此对象所表示的类或接口实现的接口。 如果此对象表示一个类&am…

maven配置junit5_JUnit 5和Selenium –改善项目配置

maven配置junit5Selenium是一组支持浏览器自动化的工具和库&#xff0c;主要用于Web应用程序测试。 Selenium的组件之一是Selenium WebDriver&#xff0c;它提供客户端库&#xff0c;JSON有线协议&#xff08;与浏览器驱动程序进行通信的协议&#xff09;和浏览器驱动程序。 Se…

形容计算机网络教室的成语,形容教育的成语

形容教育的成语形容教育的成语【不教而杀】 【弦歌之声】 【化及冥顽】 【蒙以养正】【不言之教】 【沂水春风】 【嘉言善状】 【神道设教】【不教之教】 【相夫教子】 【画荻教子】 【磨昏抉聩】【东风化雨】 【因材施教】 【教无常师】 【脱骨换胎】…

Class的 getSuperclass与getGenericSuperclass区别

Class的getInterfaces与getGenericInterface区别 http://www.cnblogs.com/maokun/p/6773076.html一、getSuperclass 返回直接继承的父类&#xff08;由于编译擦除&#xff0c;没有显示泛型参数&#xff09; Class<? super T>getSuperclass() 返回表示此 Cla…

XML——XSLT的一个简单荔枝

【0】intro to XSLT&#xff08;转自&#xff1a;http://www.w3school.com.cn/xsl/xsl_languages.asp&#xff09;0.1&#xff09;起始于 XSL XSL 指扩展样式表语言&#xff08;EXtensible Stylesheet Language&#xff09;。 万维网联盟 (W3C) 开始发展 XSL 的原因是&#xff…

Eclipse系列的隐藏宝藏– 2019年版

Eclipse Collections是一个开放源代码Java Collections框架。 在此博客中&#xff0c;我将演示该框架的五个鲜为人知的功能。 我在去年的Java Advent Calendar中发布了一个类似的博客 。 请参阅博客末尾的资源以获取有关该框架的更多信息。 1. countBy() &#xff1a;当您要查…

css html 方格,使用CSS创建方格背景

这里是一个什么样的格仔背景看起来在图形设计编辑器&#xff0c;如Photoshop或Illustrator的翻版。 (所有的CSS).checkered{height: 240px;background: -webkit-linear-gradient(45deg, rgba(0, 0, 0, 0.0980392) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.0980…

java嵌套类与内部类

一、嵌套类(Nested Classes) 使用嵌套类减少了命名冲突&#xff0c;一个内部类可以定义在一个类中&#xff0c;一个方法中甚至一个表达式中。 (1)定义 A nested(嵌套) class is any class whose declaration occurs within the body of another class or interface. A top lev…