`
victorzhzh
  • 浏览: 203046 次
  • 来自: ...
社区版块
存档分类
最新评论

左式堆学习

阅读更多

今天学习了一下左式堆,总结一下。

一、左式堆定义:

具有,如下性质

1、父节点属性值小于子节点属性值;

2、堆中的任何节点,其左儿子的零路径长>=右儿子的零路径长;

的二叉树。

注:零路径长(npl)是指:从一个节点X开始到一个不具有两个儿子的Y节点的最短路径的长,可以看出有0个或者一个儿子的节点的npl=0,并且定义npl(null)=-1;

二、左式对的节点定义:

class Node<T> {

		// 元素
		T element;
		// 左节点
		Node<T> left;
		// 右节点
		Node<T> right;
		// 零路径长
		int npl;

		public Node(T element) {
			this(element, null, null);
		}

		public Node(T element, Node<T> left, Node<T> right) {
			this.element = element;
			this.left = left;
			this.right = right;
			this.npl = 0;
		}
	}

 三、左式对的操作:

对于左式堆主要操作是“合并”,因为合并会破坏左式堆的特性,而insert、delete等操作,都会涉及到堆的合并,例如:delete根节点,相当于将一棵树边为了两个树,在将两棵树合并为一棵树。这里我们使用了一种递归的思想,若h1,h2本身是左式堆,则其子树也一定是左式堆,其子树的子树也一定是左式堆,一直退到树的每个叶子节点,都符合这个规则,那么我们合并时就可以从反方向思考,先形成一个个的小左式堆,然后在形成一棵大的左式堆。

四、左式堆定义代码:

public class LeftistHeap<T extends Comparable<T>> {
	// 左式堆节点定义
	private static class Node<T> {

		// 元素
		T element;
		// 左节点
		Node<T> left;
		// 右节点
		Node<T> right;
		// 零路径长
		int npl;

		public Node(T element) {
			this(element, null, null);
		}

		public Node(T element, Node<T> left, Node<T> right) {
			this.element = element;
			this.left = left;
			this.right = right;
			this.npl = 0;
		}
	}

	private Node<T> root;

	public LeftistHeap() {
		this.root = null;
	}

	// 合并兩個左式堆
	public void merge(LeftistHeap<T> rhs) {
		if (rhs == null)
			return;
		root = merge(root, rhs.root);
		rhs.root = null;
	}

	// 向左式堆中添加元素
	public void insert(T element) {
		root = merge(new Node<T>(element), root);
	}

	// 找寻左式堆中最小节点
	public T findMin() {
		if (isEmpty())
			return null;
		return root.element;
	}

	/**
	 * 删除堆中最小节点,由于堆的最小节点就在根上,所以可以直接删除,但是删除根后,需要在将左右子树合并
	 * 
	 * @return
	 */
	public T deleteMin() {
		if (isEmpty())
			return null;
		T minItem = root.element;
		root = merge(root.left, root.right);
		return minItem;
	}

	// 判断左式堆是否为空
	public boolean isEmpty() {
		return root == null;
	}

	// 将左式堆设置为空堆
	public void makeEmpty() {
		this.root = null;
	}

	/**
	 * 1、若第一个根节点为空,则返回第二个根节点; 2、若第一个不为空第二个为空,则返回第一个根节点;
	 * 3、一、二节点都不为空时,判断那个是根较小的节点,将根较小的节点作为第一个参数传递给merge1方法
	 * 
	 * @param h1
	 * @param h2
	 * @return
	 */
	private Node<T> merge(Node<T> h1, Node<T> h2) {
		if (h1 == null)
			return h2;
		if (h2 == null)
			return h1;
		if (h1.element.compareTo(h2.element) < 0) {
			return merge1(h1, h2);
		} else {
			return merge1(h2, h1);
		}
	}

	/**
	 * 将根节点较大的树合并到根节点较小的树上去: 1、若根节点较小的树无左子树,则将根节点较大的树作为其左子树
	 * 2、若根节点较小的树有左子树,则将根节点较大的树和根节点较小的树的右子树合并,作为根节点较小的树的右子树
	 * 3、若左子树的零路径长小于右子树的零路径长,则交换左右子树 4、根节点较小的树的零路径长修正为其右子树的零路径长度+1
	 * 
	 * @param h1
	 * @param h2
	 * @return
	 */
	private Node<T> merge1(Node<T> h1, Node<T> h2) {
		if (h1.left == null)
			h1.left = h2;
		else {
			h1.right = merge(h1.right, h2);
			if (h1.left.npl < h1.right.npl)
				swapChildren(h1);
			h1.npl = h1.right.npl + 1;
		}
		return h1;
	}

	// 交换两个子树
	private void swapChildren(Node<T> t) {
		Node<T> tmp = t.left;
		t.left = t.right;
		t.right = tmp;
	}
}

 

参考资料:《数据结构与算法分析--java语言描述》Mark Allen Weiss著

分享到:
评论

相关推荐

    左式堆C源代码

    左式堆,作为一种高效的数据结构,其在计算机科学领域中占据着重要的位置,尤其是在处理优先级队列问题时。...希望读者们能够通过学习左式堆的实现,进一步提升自己在算法和数据结构领域的知识水平。

    C++左式堆实现.zip

    左式堆是一种特殊的二叉堆数据结构,它在保持堆属性的同时,增加了额外的属性以优化某些操作。本文将深入探讨C++中左式堆的实现,并基于提供的文件`MyLeftistHeapTest.cpp`和`MyLeftistHeap.h`进行讨论。 首先,让...

    html5响应式左右分栏个人主页模板

    总的来说,这个“html5响应式左右分栏个人主页模板”涵盖了HTML5的新特性、响应式布局策略和分栏设计技巧,是学习和应用现代网页设计的一个实例。通过理解和运用这些技术,开发者可以创建出既美观又实用的跨平台网站...

    leftistheap.zip

    左式堆(Leftist Heap...左式堆的实现和应用是C++编程中提高效率的一个重要工具,对于学习和实践高级数据结构有深远的意义。通过阅读和分析给出的代码,我们可以深入理解左式堆的工作原理,进一步提升我们的编程技能。

    卡片叠加效果(左右滑动)

    通过查看和学习这个示例,你可以更直观地了解每个步骤是如何实施的。 总结来说,创建卡片叠加效果并实现左右滑动的关键在于自定义`UICollectionViewFlowLayout`,并通过适当的方法重写来调整卡片的位置、大小和旋转...

    算法合集之左偏树的特点及其应用PPT学习教案.pptx

    左偏树,又称左式堆,是一种特殊类型的二叉树,具有堆有序性质,即每个节点的值都大于或等于其左子树和右子树的值。它在数据结构和算法领域中扮演着重要角色,尤其在实现优先队列和可并堆时。左偏树的一个关键特性是...

    使用深度学习和可变形模型 检测和分割心脏 MRI中的左心室_python_代码_下载

    左心室 (LV) 的手动分割是一项繁琐而细致的任务,可能因患者、磁共振图像 (MRI) 切口和专家的不同而有所不同。直到今天,我们仍将专家的人工描述视为心脏诊断医生的基本事实...堆叠式自动编码器 可变形模型 测试和指标

    jQuery和CSS3实现堆叠式轮播图特效.zip

    堆叠式轮播图是一种创新的图片切换效果,其中图片不是简单地左右滑动,而是像卡片一样在视觉上进行堆叠和展开,从而给用户带来更加生动和立体的感受。 首先,让我们深入了解jQuery。jQuery是一个广泛使用的...

    超级简洁的jquery弹出式左右菜单

    它的设计目标是简洁且易于使用,使得开发者可以快速集成到自己的网站项目中,同时也方便用户进行收藏和学习。这种类型的菜单尤其适用于那些希望在不牺牲用户体验的情况下,保持页面加载速度的网站。 【知识点详解】...

    Python3实现堆排序算法(源代码)

    堆排序是一种高效、比较式的内部排序算法,它的基本思想是将待排序的数据集合构造成一个二叉堆(最大堆或最小堆),然后逐步缩小堆的范围,直到整个序列有序。 #### 二、堆的概念 在计算机科学中,堆通常指的是一种...

    jQuery图片堆叠左右切换插件

    6. **响应式设计**:为了适应不同设备和屏幕尺寸,插件可能采用了响应式设计,利用媒体查询(media queries)或Bootstrap等框架,确保在手机、平板和桌面电脑上都能正常显示和操作。 7. **插件封装与扩展**:优秀的...

    八数码的启发式优先算法实现

    八数码问题的启发式优先搜索算法实现是一个很好的学习实践,它不仅涉及到搜索算法,还涵盖了数据结构、优化技巧和问题建模等多个方面。通过这样的项目,开发者可以深入理解人工智能中的搜索策略,并提升解决问题的...

    二项堆的基本操作实现

    在二项堆中,每个二项树的节点个数遵循二项式系数的规律,即第i层的节点数为C(i, k),其中i是树的阶,k是二项式系数。例如,一阶二项树只有一个节点,二阶二项树有两个节点(一个父节点和一个子节点),三阶二项树有...

    左固定右边自适应框架

    标题中的“左固定右边自适应框架”是一种网页布局设计,常用于创建响应式网页,使得网页在不同设备和屏幕尺寸下能良好展示。这种布局模式通常由两部分组成:左侧栏固定宽度,常用于导航、侧边栏等功能,而右侧栏则...

    Flutter自定义实现神奇动效的卡片切换视图

    无论你是JavaScript开发者还是Flutter新手,都能通过学习和实践,掌握这一技能并为你的应用增添更多互动性和吸引力。在实际开发中,不断探索和创新,结合个人的设计理念,你将能够打造出独一无二的用户体验。

    纯css打造网上商城左侧垂直商品分类菜单

    例如,对于小屏幕设备,可能需要将垂直菜单转换为水平堆叠或折叠式菜单。 此外,为了增强用户体验,我们还可以添加一些动态效果,如过渡(transition)和动画(animation)。例如,当用户滚动鼠标经过菜单项时,...

    DataStructureAndAlgorithm.zip

    这个名为"DataStructureAndAlgorithm.zip"的压缩包文件包含了关于数据结构和算法的Java实现,具体包括了二叉堆、左式堆、AVL树、二叉搜索树以及哈希表等核心主题。接下来,我们将深入探讨这些知识点。 首先,二叉堆...

    简单的两栏流动式布局

    "简单的两栏流动式布局"是一种常见的网页布局模式,尤其适用于新手学习CSS(层叠样式表)基础知识。这种布局通常包括两个并列的区域,一个在左侧,另一个在右侧,它们在屏幕宽度允许的情况下并排显示,当屏幕尺寸...

    Android 卡片式滑动切换的ListView 源码

    在Android5.0的任务管理器中,任务卡片是以堆叠的方式呈现的,用户可以通过上滑或下滑手势来浏览和选择任务。为了实现这样的效果,开发者需要对ListView进行扩展,增加对滑动手势的处理,并且调整卡片的布局和动画...

    HTML实现可左右切换注册、登录页面模板源码.zip

    在深入研究这个源码时,我们可以学习到如何用HTML和CSS创建美观的页面布局,如何使用jQuery进行交互式开发,以及如何实现响应式设计以适应各种设备。这对于前端开发者来说是非常宝贵的经验,有助于提升网页制作技能...

Global site tag (gtag.js) - Google Analytics