算法导论 第十九章:斐波拉契堆

斐波拉契堆是由一组最小堆有序树组成,每棵树遵循最小堆性质,并且每棵树都是有根而无序的。所有树的根通过left和right指针来形成一个环形的双链表,称为该堆的根表。

对于一个给定的斐波拉契堆H ,可以通过指向包含最小关键字的树根指针H.min来访问。堆中每个节点还包含x.mark,x.degree两个域,x.degree表示x的子女表中的子女个数;x.mark表示从x上次成为另一个节点子女以来是否失掉一个孩子。

斐波拉契对的结构如下:

势能函数:

可以利用势能方法来分析斐波拉契堆的性能。其势能函数定义为:

其中m(H)指H中有标记节点的个数,t(H)表示H的根表中树的棵数。

最大度数:

假设在包含n个节点的斐波拉契堆中,节点的最大度数又一个已知的上界D(n),则有:

提取斐波拉契堆最小值代码如下:

#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct FibHeapNode
{
	int key;
	int degree;
	FibHeapNode *left;
	FibHeapNode *right;
	FibHeapNode *parent;
	FibHeapNode *child;
	bool mark;
	FibHeapNode(int k):key(k),degree(0),left(NULL),right(NULL),parent(NULL),child(NULL),mark(false){}
	}FibHeapNode;

typedef struct FibHeap
{
	int Num;   //the number of node in the heap
	FibHeapNode *min;  //the minimum heap,root node
	//int maxDegree;     //maximum degree
	}FibHeap;

void AddNodeToRootList(FibHeapNode *Hmin,FibHeapNode *x)
{
	x->right = Hmin->right;
	x->left  = Hmin ;
	if(Hmin->right !=NULL)
		Hmin->right->left = x;
	Hmin->right = x;
	}
void FibHeap_Make(FibHeap *H)
{
	H->Num=0;
	H->min=NULL;
	//H->maxDegree=0;
	}
void FibHeap_Insert(FibHeap *H,int k)
{
	FibHeapNode *x=new FibHeapNode(k);
	if(H->min==NULL)
		H->min=x;
	else
	{
		AddNodeToRootList(H->min,x);
		if(x->key < H->min->key)
			H->min = x;
		}
	H->Num++;
	}
void FibHeap_Create(FibHeap *H,int A[],int n)
{
	FibHeap_Make(H);

	for(int i=0;i<n;i++)
		FibHeap_Insert(H,A[i]);
	}
int main()
{
	int test_data[]={52,18,17,38,39,41,3,30,24,26,46,35,7,23};
	int n=sizeof(test_data)/sizeof(int);
	FibHeap *H=new FibHeap();
	FibHeap_Create(H,test_data,n);
	cout<<"Hmin="<<H->min->key<<endl;

	return 0;
	}

运行结果如下:

【注:若有错误,请指正~~~~】

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-18 21:02:48

算法导论 第十九章:斐波拉契堆的相关文章

算法导论第十九章 斐波那契堆

<算法导论>第二版中在讨论斐波那契堆之前还讨论了二项堆,但是第三版中已经把这块的内容放到思考题中,究极原因我想大概是二项堆只是个引子,目的是为了引出斐波那契堆,便于理解,而且许多经典的算法实现都是基于斐波那契堆,譬如计算最小生成树问题和寻找单源最短路径问题等,此时再把二项堆单独作为一章来讲显然没有必要.类似的堆结构还有很多,如左倾堆,斜堆,二项堆等,下次我打算开一篇博客来记录下它们的异同点. 一.摊还分析(第十七章) 这些高级的数据结构的性能分析一般是基于一个技术——摊还分析,可以理解成一种时

算法导论 第20章 斐波那契堆

一.概念 1.斐波那契堆 斐波那契堆是可合并堆 在不涉及删除的操作(除去EXTRACT和DELETE)中,操作仅需O(1)的平摊运行时间 当EXTRACT和DELETE的操作数目较小时斐波那契堆能得到较好的运行效率. 斐波那契堆不能有效地支持SEARCH操作 用于解决诸如最小生成树和寻找单源最短路径等问题的快速算法都要用到斐波那契堆. 2.斐波那契堆的结构 斐波那契堆由一组最小堆构成,这些最小堆是有根的无序树. 结点结构: key: 关键字,作为排序.判断结点大小的标准 left, right:

ACM/ICPC算法训练 之 数学很重要—斐波拉契●卢卡斯数列(HNNUOJ 11589)

看到这个标题,貌似很高大上的样子= =,其实这个也是大家熟悉的东西,先给大家科普一下斐波拉契数列. 斐波拉契数列 又称黄金分割数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.34.…… 在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*) 在现代物理.准晶体结构.化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从1963起出版了以<斐波纳契数列季刊>为名的一份数学杂志,用于专门刊载这方面的

算法导论第十二章__二叉搜索数

package I第12章__二叉搜索树; //普通二叉树 public class BinaryTree<T> { // -----------------------数据结构--------------------------------- private int height = 0; private Node<T> rootNode; class Node<T> { T t; int key; Node left; Node right; public Node

剑指offer-第二章算法之斐波拉契数列(青蛙跳台阶)

递归与循环 递归:在一个函数的内部调用这个函数. 本质:把一个问题分解为两个,或者多个小问题(多个小问题相互重叠的部分,会存在重复的计算) 优点:简洁,易于实现. 缺点:时间和空间消耗严重,如果递归调用的层级太多,就会超出栈容量. 循环:通过设置计算的初始值及终止条件,在一个范围内重复运算. 斐波拉契数列 题目一:写一个函数,输入n,求斐波拉契(Fibonacci)数列的第n项,定义如下: 第一种解法:用递归的算法: long long Fabonacci(unsigned int n) { i

经典算法___斐波拉契数列

分享一段斐波拉契数列的例子,不过我对算法没怎么接触过,只能写出最简单,最基本的 def fibs(num):     result = [0,1]         #斐波拉契数列初始变量          for i in range(num-2):      #循环,因为上边已经有两个变量,所以-2              result.append(result[-2] + result[-1])       #吧倒数第一项与倒数第二项相加作为最后一项的值              ret

题目九:斐波那契数列

///////////////////////////////////////////////////////////////////////////////////////////// // 13.题目九:斐波那契数列 /*写一个函数,输入N,求斐波那契(Fibonacci)数列的第N项. F(n) = {0    n == 0;         1    n == 1;         F(n -1) + F(n -2) n > 1;         } */ static int s_Ru

笔试算法题(46):简介 - 二叉堆 &amp; 二项树 &amp; 二项堆 &amp; 斐波那契堆

二叉堆(Binary Heap) 二叉堆是完全二叉树(或者近似完全二叉树):其满足堆的特性:父节点的值>=(<=)任何一个子节点的键值,并且每个左子树或者右子树都是一 个二叉堆(最小堆或者最大堆):一般使用数组构建二叉堆,对于array[i]而言,其左子节点为array[2*i],其右子节点为 array[2*i+1]:二叉堆支持插入,删除,查找最大(最小)键值的操作,但是合并二叉堆的复杂度较高,时间复杂度为O(N):但是二项堆或者斐波 那契堆则仅需要O(logN): 二项树(Binomial

优先队列——斐波那契堆

1. 引言 最近一直在写最短路径的迪杰斯特拉与双向迪杰斯特拉算法,使用优先队列可以极大的加快算法的运行效率.比如在OL数据集中,对于迪杰斯特拉算法用优先队列(二叉堆实现)代替普通的数组(数据结构书中提供的算法)快了将近60倍. 由上可得如何实现优先队列对迪杰斯特拉.双向迪杰斯特拉以及其它用到优先队列的最短路径求解算法(如reach.A*)等至关重要.另外对于一些其他用到优先队列的问题也具有相当的影响. 对于优先队列来说,只需要入队.出队即可,因为该文章只关注堆的插入(push)与删除(delet