【数据结构】优先队列专题 左式堆

《数据结构与算法分析》左式堆详解 前言:       这篇博客也是补上休假拉下的内容。。博客已经严重滞后了。。 我的github: 我实现的代码全部贴在我的github中,欢迎大家去参观。 https://github.com/YinWenAtBIT 介绍: 定义:      左式堆(Leftist Heaps)又称作最左堆、左倾堆,是计算机语言中较为常用的一个 阅读详情


1. 左式堆概述

为了有效支持合并操作,即以 o ( N ) o(N) o(N) 时间进行 Merge ,我们需要使用动态的链接结构或者静态链表。如果只使用数组形式的堆结构,在进行合并时光拷贝一个数组到另一个数组中,就将花费 Θ ( N ) \Theta(N) Θ(N) 的时间。

左式堆 (leftist tree, leftist heap ),或者说左偏堆、左偏树,是一种优先队列实现方式,属于可并堆(除了左式堆外,还有如斜堆、二项堆、配对堆、斐波那契堆等)。在统计问题、最值问题、模拟问题和贪心问题等等类型的题目中,都有着广泛的应用。

左式堆和二叉堆一样具有结构性质和堆序性质,它具有和其他堆一样的堆序性质,同时也是一棵二叉树。和二叉堆唯一的区别在于:左式堆是很不平衡的。

2. 左式堆性质

为了完全了解左式堆的性质,我们需要以下定义:

  • 外结点:只有一个儿子或没有儿子的节点,即左右儿子至少有一个为空节点的节点。
  • 距离/零路径长 null path length :npl(X) 定义为 X 结点到它的后代中离它最近的外结点的最短路径长度,即两结点之间路径的权值和。特别的,外结点的距离为 0 ,空结点的距离为 npl(NULL) = -1 。
  • 左偏树/左式堆:一种满足左偏性质的堆有序的二叉树,其左偏性质体现在左儿子的距离大于等于右儿子的距离。
  • 左偏树/左式堆的距离:我们将一棵左偏树根结点的距离作为该树的距离。

左式堆的基本性质如下:

  • 满足堆的基本性质,如小根堆中,结点的键值小于等于其左右儿子结点的键值
  • 对于任意结点,左儿子的距离大于等于右儿子的距离
  • 对于任意结点,其距离等于它右儿子的距离加一
  • 一个距离为 d d d 的左式堆,其结点数必然不小于 2 d + 1 − 1 2^{d + 1} - 1 2d+1−1 个结点
  • 对于一个有 n n n 个结点的左式堆,其根结点的距离不超过 log ⁡ n \log n logn

下图中,距离或者说 null path length 标记在结点内部。很明显,只有左边的树是左式的,因为它之中任何结点左儿子的距离都大于等于右儿子的距离:
在这里插入图片描述

左式堆性质:对于堆中的任意结点 X ,其左儿子的距离至少与右儿子的距离一样长。任一结点的距离,都比它的诸儿子结点的距离的最小值(就是右儿子的距离)多 1 。

上述性质不仅确保了树平衡的要求,而且偏重于使树向左增加深度,甚至很可能存在由左结点形成的长路径构成的树,在实际上更有利于合并操作——因此,得名左式堆 leftist heap 。

由于左式堆倾向于增长左路径,所以右路径应该短。甚至,沿着左式堆右侧的右路径是该堆中最短的路径。不然,就存在一条路径通过某个结点 X 向左儿子深入,X 就破坏了左式堆的左偏性质。

定理:在右路径上有 r r r 个结点的左式堆必然至少存在 2 r − 1 2^r - 1 2r−1 个结点。或者说,一个距离为 d d d 的左式堆,其结点数必然不小于 2 d + 1 − 1 2^{d + 1} - 1 2d+1−1 个结点。

证明:数学归纳法证明。

  • 如果 r = 1 r = 1 r=1 ,则必然至少存在一个树结点。
  • 设定理对 1 , 2 , … , r 1,2,\dots,r 1,2,…,r 个结点成立。考虑在右路径上有 r + 1 r + 1 r+1 个结点的左式树。此时,根具有在右路径上含有 r r r 个结点的右子树,以及在右路径上至少含有 r r r 个结点的左子树(否则就不是左式堆)。对这两个子树应用归纳假设,可知每棵子树上最少有 2 r − 1 2^r - 1 2r−1 个结点,加上根结点,于是该树上最少有 2 r + 1 − 1 2^{r + 1} - 1 2r+1−1 个结点。

从这个定理可知,对于一个有 n n n 个结点的左式堆,其根结点的距离,即右路径最多含有 ⌊ log ⁡ ( n + 1 ) ⌋ \lfloor \log (n + 1) \rfloor ⌊log(n+1)⌋ 个结点。


3. 左式堆操作和代码实现

对左式堆操作的一般思路是:将所有的工作放到右路径进行,从而保证树的深度更短。不过,对于右路径的 insert, merge 可能破坏左式堆性质。尽管恢复起来也很容易。

左式堆可能有的基本结点信息,具体实现时可以酌情添加和修改:

  • v a l val val :键值
  • l e f t left left :左儿子
  • r i g h t right right :右儿子
  • d i s t dist dist :距离
  • f a t h e r father father :父亲

左式堆的C++结构:

#include <bits/stdc++.h>
using namespace std;

template <typename Comparable>
class LeftistHeap {
private:
	struct LeftistNode {
		Comparable element;  //数据值 
		LeftistNode *left;   //左儿子 
		LeftistNode *right;  //右儿子 
		int dist;			 //距离 
		
		LeftistNode(const Comparable &theElement, LeftistNode *lt = nullptr, 
					LeftistNode *rt = nullptr, int d = 0)
			: element(theElement), left(lt), right(rt), dist(d) { }
	};
	LeftistNode *root;
	LeftistNode *merge(LeftistNode *h1, LeftistNode *h2);  	//私有的合并方法 
	LeftistNode *merge1(LeftistNode *h1, LeftistNode *h2);  //实际执行的merge方法 
	
	void swapChildren(LeftistNode *t);						//交换左右子树	
	//void reclaimMemory(LeftistNode *t);						
	//LeftistNode *clone(LeftistNode *t) const;
public:
	LeftistHeap();							//建立空堆 
	LeftistHeap(const LeftistHeap &rhs);	//复制rhs建堆 
	~LeftistHeap();							//析构函数 
	bool empty() const;				   		//判断是否为空 
	const Comparable &findMin() const; 		//找到最小值 
	 
	void insert(const Comparable &x);  		//插入:合并单结点和堆即可 
	void deleteMin();				   		//删除最小值 
	void deleteMin(Comparable &minItem); 	//删除并返回最小值 
	void makeEmpty();				   		//清空左式堆 
	void merge(LeftistHeap &rhs);	   		//公共的合并方法 
	
	const LeftistHeap& operator=(const LeftistHeap &rhs); //赋值运算符函数 
};

(1) 合并操作

左式堆最基本也最重要的操作是合并,毕竟是可并堆。下面介绍一个简单的递归算法,输入是两个左式堆 H 1 , H 2 H_1, H_2 H1​,H2​ ,如下图,这两个堆都是左式堆,而且是小根堆:
在这里插入图片描述
如果两个堆中有一个堆为空,就直接返回另一个堆。否则为了合并两个堆,需要比较它们的根。首先,递归将根值较大的堆和根值较小的堆的右子堆合并。这里递归地将 H 2 H_2 H2​ 与 H 1 H_1 H1​ 中根值为 8 8 8 的右子堆合并,得到下图的堆:
在这里插入图片描述

这棵树是递归形成的,虽然现在不知道是如何得到的,不过处理基准情形后,我们假设递归步骤能够成立,合并可以完成。接着要让这个新的堆成为 H 1 H_1 H1​ 的根的右儿子:
在这里插入图片描述
这时的堆满足堆序性质,但不满足左偏性质,不是左式堆。可以看出其根结点的左子树的距离为 1 1 1 ,而根的右子树的距离为 2 2 2 。左式堆的性质在根处被破坏。

但是树的其余部分必然是左式的,由于递归步骤,根的右子树是左式的,左子树没有变化还是左式的。所以,只要对根进行调整就好了。为了让整个树都是左式的,交换树根的左儿子和右儿子,并更新根结点的距离,新的距离是新的右儿子的距离加一,这样就完成了 merge 。
在这里插入图片描述

可以手动模拟这个过程,就能够知道这个递归算法如何运行了。步骤总结如下:(函数 merge(x, y) 表示合并 x, y ,返回值是合并后的根结点)

  • 如果有一个根结点是空,则返回另一个根结点;
  • 设 x 是 x, y 中权值较小的那个,即 v a l x ≤ v a l y val_x \leq val_y valx​≤valy​ 。若 x 的权值大于 y,交换 x, y 进行合并即可;
  • 为了维护小根性质,合并好的堆的堆顶一定还是 x ,所以递归向下合并 x 的子树(左右都行,一般用右子树)和 y ;
  • 递归结束后,y 和 x 的右子树形成一个新的左式堆,其结果成为 x 的新的右子树;
  • 合并后可能破坏 x 的左偏性质,所以需要检查 x 此时左右子树的距离,如果左子树的距离小于右子树,就交换左右子树,更新 x 的距离为新的右子树的距离加一。

代码如下:

//公有的merge方法将rhs合并到已有的优先队列(左式堆),rhs成为空堆 
void LeftistHeap::merge(LeftistHeap &rhs) {
	//rhs必须和this不同
	if (this == &rhs) return; //不接受h.merge(h) 
	root = merge(root, rhs.root); //调用私有的merge方法merge(h1, h2); 
	rhs.root = nullptr;           //rhs的root指向空 
}
//内部方法合并两个根,消除一些特殊情形,保证H1有较小根; 
//作为驱动程序调用merge1进行实际的合并 
LeftistNode *merge(LeftistNode *h1, LeftistNode *h2) {
	if (h1 == nullptr) return h2;
	if (h2 == nullptr) return h1; 
	if (h1->element < h2->element) //保证h1是较小的根 
		return merge1(h1, h2); 
	else 
		return merge1(h2, h1);
}
//merge1进行实际的合并和距离的调整 
LeftistNode *merge1(LeftistNode *h1, LeftistNode *h2) {
	if (h1->left == nullptr) //单结点
		h1->left = h2; 	     //h1的其他部分已经准确了
	else {
		h1->right = merge(h1->right, h2);
		if (h1->left->dist < h1->right->dist) 
			swapChildren(h1);
		h1->dist = h1->right->dist + 1;
	}
	return h1;
}

执行合并的时间与右路径的长的和成正比。因此,合并两个左式堆的时间为 O(logN) \text{O(logN)} O(logN) 。

(2) 插入操作

插入只是合并的特殊情况,可以看成是单结点堆和更大的堆的 merge。

void insert(const Comparable &x) { //push,新建一个新结点和堆合并即可
	root = merge(new LeftistNode(x), root);
}

(3) 删除最小值操作

由于是小根堆,可以除掉根从而得到两个堆,接着将两个堆进行合并即可。执行一次 deleteMin 操作的时间是 O(logN) \text{O(logN)} O(logN) 。

void deleteMin() {
	if (empty()) throw underflow_error("LeftistHeap Empty");
	LeftistNode *oldRoot = root;
	root = merge(root->left, root->right);
	delete oldRoot;
}

void deleteMin(Comparable &minItem) {
	minItem = findMin();
	deleteMin();
}
优先队列基础知识(三)---左式堆 本文主要就是介绍这样的堆数据结构---左式堆,实现对数时间的合并操作。 阅读详情

相关推荐

【数据结构】优先队列进阶:左式堆的高效合并与应用

本文深入探讨了左式堆这一高效的可并堆数据结构。针对传统二叉堆合并效率低的痛点,详细解析了左式堆通过维护零路径长和左偏性质,实现O(log n)时间复杂度合并操作的原理与算法。文章结合任务调度等实战场景,对比了不同可并堆的优劣,并提供了清晰的实现指南与调试技巧,为需要动态合并优先队列的应用提供了专业解决方案。

weixin_29201933的博客 624

左式堆

1 相关定义 1.1 零路径长度定义: 到没有两个儿子的节点最短距离, 即零路径长Npl 定义为 从 X 到一个没有两个儿子的 节点的最短路径的长;也即, 非叶子节点到叶子节点的最少边数,其中NULL的零路径长为-1, 叶子节点的零路径长为0; (零路径长的定义—— 非叶子节点到叶子节点的最少边数,非常重要,因为左式堆的定义是基于零路径长的定义的) 1.2 左式堆定义: 一棵具有堆序性质的二叉树...

miracleon的博客 1446

Omnibox 2.11 NAS部署指南:家庭影音中枢的轻量化落地实践

家庭影音平台本质是本地化内容调度中枢,其核心在于聚合NAS媒体库、统一管理直播/IPTV/音频/视频等多源内容,并通过智能元数据匹配与硬解加速实现零门槛播放体验。技术原理上依赖Java轻量Web容器(Jetty)、SQLite嵌入式数据库双缓存架构,以及宿主机FFmpeg动态链接与HTTP/2直播代理治理能力。该方案显著降低4K播放卡顿、EPG加载失败、海报缺失等高频问题,适用于群晖、飞牛、绿联等主流NAS设备,尤其适配ARM64芯片与Realtek网卡等国产硬件生态。本文聚焦Omnibox 2.11在真实

weixin_30846347的博客 471

左式堆(数据结构篇)

讲述数据结构中的左式堆

hellmorning的博客 923

DataWorks数据安全治理最佳实践

DataWorks基于数据安全治理的常见思路,针对资产梳理、技术体系建设和运营体系建设,提供了一系列数据安全产品能力,您可通过“基础防护建设、数据安全防护措施及策略增强建设、数据安全持续运营”三个阶段在DataWorks上落地数据安全治理项目。参考本文启动数据安全治理项目前,建议您先了解DataWorks数据安全产品相关能力了解DataWorks数据安全产品能力后,您可参考如下三个阶段在DataWorks上落地数据安全治理项目。

soso1968的博客 1438

十五、【优先级队列】左式堆(leftist heap)

一、左式堆存在的意义 除了标准的插入和删除操作,堆结构在实际应用中的另一个常见的操作是合并,即将堆A和堆B重新组织成一个堆。若采用最基本的完全二叉堆数据结构,其最高效的实现策略是采用Floyd建堆算法将堆A和堆B直接重构成一个新堆,但是该算法的时间复杂度为O(n),这种性能在实际中不让人满意,而左式堆结构能保证在合并操作中只需要调整很少的点,所以能保证合并操作的时间复杂度低至O(logn)。而且...

天涯明月刀的博客 1355

信捷CODESYS平台伺服电机转矩控制模式应用与切换

信捷CODESYS二次开发软件:XS Studio 在运动控制中的转矩控制案例

weixin_64614866的博客 1万+

左式堆(leftist heap)

堆合并 堆合并是指,对于任意两个堆,将其合并为一个更大的堆,如下图所示: 为了解决这个问题,我们可以首先进行一些初步的尝试。 简明的插入策略 最简明的思路,无非是将一个堆中的元素,逐个删除并且依次插入到另一个堆中。不妨设两个堆的规模分别为m和n,则这种策略的时间复杂度为O(m * (logm + log(m + n))) = O(m * log(m + n))。 Floyd批量建堆算法 ...

Shine__Wong的博客 3889

深度学习分类任务中,正负样本比例失衡的5种实战解决方案(附代码)

本文深入探讨了深度学习分类任务中正负样本比例失衡的5种实战解决方案,包括智能采样技术、动态数据增强、损失函数工程、模型架构创新和训练策略优化。针对信用卡欺诈检测、医疗诊断等场景,提供了详细的代码实现和评估方法,帮助开发者有效解决样本不平衡问题,提升模型在真实场景中的表现。

h9j8k7l6m5n的博客 425

人形机器人人机交互解决方案(2026完整版)

《人形机器人人机交互解决方案(2026完整版)》摘要 本项目针对2026年人形机器人产业爆发式增长需求,提出了一套完整的人机交互解决方案。方案包含十大核心模块(语音识别、情感识别、手势识别等),采用五层架构设计,实现多模态融合交互,响应时间≤32ms,准确率≥99%。覆盖制造业巡检、家庭服务等10大场景,适配20+主流机型。项目总投资4.1亿元,预期年营收8.2亿元,将申请专利120项,培养专业人才300人。通过技术创新解决当前交互体验生硬、安全可控性不足等痛点,助力我国人形机器人产业实现从"跟跑

随读手记 776

优先队列之左式堆

1.左式堆的性质 我们把任一节点X的零路径长(null path length,NPL)Npl(X)定义为从X到一个没有两个儿子的节点的最短路径的长。因此,具有0个或1个儿子的节点的Npl为0,而Npl(NULL) = -1。 左式堆性质是:对于堆中的每一个节点X,左儿子的零路径长至少与右儿子的零路径长一样大。下图左边是左式堆,右边不是。 2.左式堆的操作 (1)合并

Coding365 808

STM32 W5500 Freemodbus Modbus TCP协议功能实现

STM32F103VCT6 W5500(SPI1),实现Modbus-TCP协议的功能

坚韧与专注 2万+

优先队列——二叉堆、d堆、左式堆、斜堆

完整的PPT下载:http://download.youkuaiyun.com/detail/sangni007/4850483   实现优先队列结构主要是通过堆完成,主要有:二叉堆、d堆、左式堆、斜堆、二项堆、斐波那契堆、pairing 堆等。     1. 二叉堆   1.1. 定义 完全二叉树,根最小。 存储时使用层序。   1.2. 操作 (1). insert(上滤)

nashouat个人空间 2098

Python re库【正则表达式操作库】全面讲解及代码示例

以下是Pythonre库的全面讲解,包含主要功能、常用方法及代码示例。完整代码和注释附后。正则表达式(Regular Expression)是用于匹配、查找、替换字符串的工具,通过特定语法定义模式。?{n}[...][a-z]A|B\d[0-9]\D\s\S\w\Wre从字符串匹配模式,返回Match对象或None。在字符串中第一个匹配项,返回Match对象或None。返回所有匹配项的。返回所有匹配项的Match对象)。替换匹配项,返回新字符串。根据模式分割字符串,返回列表。通过。

记录点滴 1162

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

结构之美——优先队列基本结构(四)——二叉堆、d堆、左式堆、斜堆

实现优先队列结构主要是通过堆完成,主要有:二叉堆、d堆、左式堆、斜堆、二项堆、斐波那契堆、pairing 堆等。   1. 二叉堆   1.1. 定义 完全二叉树,根最小。 存储时使用层序。   1.2. 操作 (1). insert(上滤) 插入末尾 26,不断向上比较,大于26则交换位置,小于则停止。   (2). deleteMin(下滤) 提取末尾元素

小熊不去实验室 5552

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

二十三、数据结构之左式堆

不想进行过多的解释。 左式堆:顾名思义,左树一定大于右树,就这一个定理,时刻满足这个定理就是坐式堆,再加个从上到下,权重逐渐递减就是个优先坐式堆。手动滑稽。。。。。。。。。。。。。 直接上代码了,自己研究吧,蛮简单的,手动狗头。。。。。。。。。。 #include <stdio.h> #include <stdlib.h> //定义数据类型 typedef int...

蛋蛋 283

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

看图说话之左式堆(优先队列)——原理解析及java实现

介绍优先队列的重要实现——左式堆的合并,插入,删除,建堆等基本原理以及java代码实现。

涂印的博客 3436

左式堆Java_【数据结构】回顾优先队列(堆)

1.优先队列有两项基本操作:插入(insert)和删除最小项(deleteMin),后者的工作是找出、返回和删除优先队列中最小的元素。而insert操作则等价于enqueue(入队),deleteMin则等价于dequeue(出队)。补充:C++提供2个版本的deleteMin,一个删除最小项,另一个在删除最小项的同时在通过引用传递的对象中存储所删除的值。 2.优先队列的类接口template c...

weixin_29471009的博客 127

左式堆实战:5分钟搞懂优先队列的高效合并技巧(附C++代码)

本文深入解析左式堆如何通过“左偏”设计实现优先队列的高效合并。相比传统二叉堆,左式堆牺牲部分平衡性,确保合并操作在对数时间内完成,特别适用于流式数据处理、多路归并等需要频繁合并的场景。文章附有完整的C++实现代码,帮助开发者快速掌握这一数据结构。

wine的专栏 1065

为什么左式堆总向左倾斜?图解优先队列的冷门数据结构

本文深入解析了左式堆这一为高效合并而设计的优先队列数据结构。通过图解和原理剖析,揭示了其刻意向左倾斜的秘密:利用零路径长和左偏性质,将合并操作的时间复杂度优化至O(log N)。文章对比了其与经典平衡树的差异,并提供了从零实现的实战代码,帮助开发者理解在需要频繁合并队列的场景下如何做出最优选择。

weixin_29219189的博客 321

数据结构笔记(七)——左式堆/左偏树(leftist heap)(2)

前面二叉堆实现了优先队列基本的插入和删除最小元操作,但如果想要将两个堆合并的话就不太容易了,我们要把一个数组里的数据拷贝到另一个数组,如果数组1和数组2大小相同,那么合并操作的时间就是O(N)。果然合并还是需要指针呀,所以我们提出了左式堆,但是注意指针操作实际会比乘除运算更加耗费时间。 左式堆(Leftist Heap)也有结构和有序性。左式堆的有序性和二叉堆一样,父亲小于所有的儿子。它不再是用...

xitie8523的博客 724

【数据结构】(五)堆(优先队列):二叉堆、d堆、左式堆、斜堆与二项队列

堆(Heap) 堆(Heap)又称为优先队列(priority queue),在队列的基础上,堆允许所有队列中的元素不一定按照先进先出(FIFO)的规则进行,而是使得每个元素有一定的优先级,优先级高的先出队列。 这类数据结构属于计算机科学中最雅致的一种 优先队列至少存在两个重要的操作: insert:插入,使得数据入队列,是一种有约束的enqueue操作 deleteMin:删除最小项,找出...

超级超级小天才的博客 1697

优先队列之左式堆(JAVA实现)

优先队列之左式堆理解及JAVA实现

MC的博客 842

【数据结构】左式堆:高效合并的优先队列实现

本文深入解析了左式堆这一高效的数据结构,它专为解决优先队列的合并痛点而生。通过引入零路径长和左偏性质,左式堆实现了O(log N)时间复杂度的合并操作,特别适用于多路归并、动态任务调度等需要频繁合并堆的场景。文章详细阐述了其核心原理、递归合并算法,并提供了完整的C++实现代码。

t8u9v0w1x的博客 208

结构之美——优先队列基本结构(四)——二叉堆、d堆、左式堆

实现优先队列结构主要是通过堆完成,主要有:二叉堆、d堆、左式堆、斜堆、二项堆、斐波那契堆、pairing 堆等。   1. 二叉堆   1.1. 定义 完全二叉树,根最小。 存储时使用层序。   1.2. 操作 (1). insert(上滤) 插入末尾 26,不断向上比较,大于26则交换位置,小于则停止。   (2). deleteMin(下滤) 提取末尾元素,放

xyjikl 685
上一篇: 【算法学习】字符串 KMP算法、next数组性质
下一篇: 【算法学习】平衡树专题 Treap树
memcpy0
博客等级 码龄9年 2001粉丝 1591原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

memcpy0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值