堆基础总结(算法导论)

0.二叉堆

排序和顺序统计学中的堆排序所用到的堆,是一棵完全二叉树。存放时利用了二叉树,父亲节点序号(i),子节点序号(2*i,2*i+1)的性质
堆的建立,调整,输出实例如下:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
//root从data[1]开始存起 
//我想到的是左右孩子先比较,返回大孩子序号。大孩子再与父节点比较,如果不调换,调整结束,直接返回;如果调换,调换后,再将大孩子作为序号递归调用调整函数。但他使用迭代似乎可以更加的简洁 
//大顶堆 
void heapAdjust(vector<int> &data,int s,int l)//data为数据源,s为需要调整的节点 ,l为有效节点个数 
{
	int rc=data[s];//要调整的数值 
	int i=s;
	while(i<=l/2)
	{
		s=i;//此时s已经作为一个temp,临时的辅助变量 
		if(data[2*i]<data[2*i+1])//左孩子的数值小于右孩子的数值
		{
			i=2*i+1;//我要右孩子 
		}
		else
		{
			i=2*i;//我要左孩子 
		}
		
		if(rc>data[i])//父节点数值大于大孩子数值
		{
			return;//无需调整,结束堆调整 
		} 
		else
		{
			swap(data[s],data[i]);//小于则交换父节点和子节点的数值
		}	 
	}
}

void heapMake(vector<int> &data,int l)
{
	for(int i=l/2;i>=1;i--)
	{
		heapAdjust(data,i,l);
	}
}

void heapOutput(vector<int> &data,int l)
{
	for(int i=0;i<l;i++)
	{
		cout<<data[1]<<"\t";
		data[1]=-1;
		swap(data[1],data[l-i]);
		heapAdjust(data,1,l-i-1);
	}	
}

int main()
{
	vector<int> data;
	int l;
	cin>>l;
	data.push_back(-1);
	for(int i=0;i<l;i++)
	{
		int temp;
		cin>>temp;
		data.push_back(temp);
	}
	if(l%2==0)
	{
		data.push_back(-1);
	}
	heapMake(data,l);
	heapOutput(data,l);
}

1.二项堆

a.二项树

定义:

二项树Bk是一种递归定义的有序树。二项树B0只包含一个结点。二项树Bk由两个子树Bk-1连接而成:其中一棵树的根是另一棵树的根的最左孩子。

性质:

1)共有2的k次方个结点;

2)树的高度为k;

3)在深度i处恰有(上k,下i)(因此叫二项树)个结点,其中i=0,...,k;

4)根的度数为k,它大于任何其他结点的度数,并且,如果对根的子女从左到右编号为k-1,k-2,...,0,子女i是子树Bi的根。

b.二项堆

定义:由一组二项树组成,同时满足以下两个性质

1)H中的每个二项树遵循最小堆的性质:结点的关键字大于等于其父结点的关键字。

2)对于任意非负整数k,在H中至多有一棵二项树的根具有度数k。(如下图对于非负整数0,1,2,3,至多只有一棵度数为0,1,2,3的二项树)


存储模型:

struct heapNode
{
	int key;//该节点的值
	int degree;//当前节点作为根节点的树的度数,也即k
	heapNode *parent;//父亲节点,对于每棵树的根节点而言没有父亲节点,值为NULL
	heapNode *chlid;//该树的第一个孩子
	heapNode *sibling;//串联同一父节点下的所有子节点 
	heapNode(int x):key(x),degree(0),parent(NULL),child(NULL),sibling(NULL){}
}; 
class heap
{
	private:
		heapNode *head;
		heapNode *min;
};

c.二项堆的建立,插入,删除,合并等
#include<iostream>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
//析构函数和复制构造函数不再重载 
struct heapNode
{
	int key;//该节点的值,为方便操作,关键字均大于0 
	int degree;//当前节点作为根节点的树的度数,也即k
	heapNode *parent;//父亲节点,对于每棵树的根节点而言没有父亲节点,值为NULL
	heapNode *child;//该树的第一个孩子
	heapNode *sibling;//串联同一父节点下的所有子节点 
	heapNode(int x):key(x),degree(0),parent(NULL),child(NULL),sibling(NULL){}
}; 
struct heap
{
	heapNode *root;
	heapNode *min;	
	heap():root(NULL),min(NULL){}	
};
/***********************堆合并的辅助函数*************以下*********/
void mergeSort(heapNode *p,heapNode *q,heapNode *m)
{
	while(p!=NULL&&q!=NULL)
	{
		if(p->degree<=q->degree)
		{
			m->sibling=p;
			m=m->sibling;
			p=p->sibling;
		}	
		else
		{
			m->sibling=q;
			m=m->sibling;
			q=q->sibling;
		}
	}
	while(p!=NULL)
	{
		m->sibling=p;
		m=m->sibling;
		p=p->sibling;
	}
	while(q!=NULL)
	{
		m->sibling=q;
		m=m->sibling;
		q=q->sibling;
	}
}

void link(heapNode *root,heapNode *child)
{
	child->sibling=root->child;
	child->parent=root;
	root->child=child;
	root->degree++;
} 

void adjustMin(heapNode *root)
{
	while(root->child!=NULL)
	{
		if(root->key>root->child->key)
		{
			swap(root->key,root->child->key);
			root=root->child;
		}
		else
		{
			return;
		}
	}
}

void adjustD(heapNode *m,heapNode *mpre)
{
	if(m->sibling==NULL)
	{
		return;
	}
	if(m->degree>m->sibling->degree)
	{
		heapNode *temp=m->sibling;
		m->sibling=temp->sibling;
		temp->sibling=m;
		mpre->sibling=temp;
		mpre=temp;
	}
} 

void heapMin(heap *h)
{
	heapNode *root=h->root;
	int minkey=root->key;
	h->min=root;
	while(root->sibling!=NULL)
	{
		if(root->sibling->key<minkey)
		{
			minkey=root->sibling->key;
			h->min=root->sibling;
		}
		root=root->sibling;
	}
} 
/***********************堆合并的辅助函数***************以上********/
//合并两个堆 
void unionHeap(heap *a,heap *b)
{
	heapNode *p=a->root;
	heapNode *q=b->root;
	if(p==NULL)
	{
		a->root=b->root;//仅在该题中,c指向的那块内存可以是b指向的那块,没必要要重载复制构造函数 
		return; 
	}
	if(q==NULL)
	{
		return;
	}
	heapNode *t1=new heapNode(-1);//为方便计算所设的头结点 
	heapNode *m=t1;
	mergeSort(p,q,m);
	m=t1->sibling;
	heapNode *mpre=t1;
	while(m->sibling!=NULL)
	{
		if(m->degree!=m->sibling->degree)
		{
			m=m->sibling;
			mpre=mpre->sibling;
		}
		else
		{
			heapNode *temp=m->sibling;
			m->sibling=temp->sibling;
			link(m,temp);//链接两个堆的根 
			adjustMin(m);//调整,保持每棵二项树树根最小的性质 
			adjustD(m,mpre);//调整,保证度数小的二项树在前,以防止间隔的两棵二项树具有相同的度,却得不到合并的现象 
		}
	}
	a->root=t1->sibling;
	heapMin(a);
	return;
}
//遍历(遍历函数有误) 
void levelTraversal(heap *r)
{
	queue<heapNode*> q;
	q.push(r->root);
	while(!q.empty())
	{
		heapNode *root=q.front();
		q.pop();
		if(root->key>=0)
		{
			cout<<"key("<<root->key<<") degree("<<root->degree<<")"<<"\t";
		}
		if(root->child!=NULL)
		{
			q.push(root->child);	
		}
		if(root->sibling!=NULL)
		{
			q.push(root->sibling);
		}
	}	
	cout<<endl;
}
//插入一个节点,就先构造一个只有一个节点的二项堆,然后在和原二项堆合并 
void insertNode(int x,heap *h)
{
	heap *temp=new heap();
	heapNode *t=new heapNode(x);
	temp->root=t;
	temp->min=t;
	unionHeap(h,temp);
} 
/***********************删除关键字的辅助函数***************以下********/
//删除有最小关键字的节点 
void deleteMinKeyNode(heap *h)
{
	//把含最小(根)节点的那棵二项树给拎出来 
	heapNode *temp;  
	if(h->root==h->min)
	{
		temp=h->root;
		h->root=temp->sibling;
	}
	else
	{
		heapNode *pre=h->root;
		while(pre->sibling!=h->min)
		{
			pre=pre->sibling;
		}
		temp=pre->sibling;
		pre->sibling=temp->sibling;
	}
	//删除最小节点 
	heapNode *dele=temp;
	temp=temp->child;
	delete dele;
	if(temp==NULL)//无孩子,度为0,直接返回 
	{
		return;
	}
	//把最小节点原来的孩子逆序排列
	stack<heapNode*> s;
	while(temp!=NULL)
	{
		heapNode *tempbother=temp->sibling;
		temp->parent=NULL;
		temp->sibling=NULL;	
		s.push(temp);
		temp=tempbother;
	}
	//组成新堆 
	heap *t=new heap();
	t->root=s.top();
	s.pop();
	temp=t->root;
	while(!s.empty())
	{
		temp->sibling=s.top();
		temp=temp->sibling;
		s.pop();
	}
	//新堆与原堆合并
	unionHeap(h,t); 
	heapMin(h);
}
//减少关键字的值成负值-1 
void decreaseKey(heap *h,int key)
{
	heapNode *temp;
	queue<heapNode*> q;
	q.push(h->root);
	while(!q.empty())
	{
		heapNode *root=q.front();
		q.pop();
		if(root->key==key)
		{
			temp=root;
			break;
		}
		if(root->child!=NULL)
		{
			q.push(root->child);	
		}
		if(root->sibling!=NULL)
		{
			q.push(root->sibling);
		}
	}
	temp->key=-1;
	while(temp->parent!=NULL)
	{
		swap(temp->parent->key,temp->key);
		temp=temp->parent;			
	}
	heapMin(h);
} 
/***********************删除关键字的辅助函数***************以上********/
//删除关键字
void deleteKey(heap *h,int key) 
{
	//先减少关键字的值,使它达到根节点 
	decreaseKey(h,key);
	//然后删除这个最小根节点
	deleteMinKeyNode(h); 
}
int main()
{
	heap *h=new heap();
	heapNode *ht0=new heapNode(11);
	h->root=ht0;
	h->min=ht0;
	insertNode(12,h);
	insertNode(13,h);
	 
	heap *h1=new heap();
	heapNode *ht1=new heapNode(21);
	h1->root=ht1;
	h1->min=ht1;
	insertNode(22,h1);
	insertNode(23,h1);
	
	unionHeap(h,h1);
	levelTraversal(h);
	deleteKey(h,23);
	levelTraversal(h);
}

3.斐波那契堆

类似于平衡树-红黑树与高度自平衡的AVL的关系。斐波那契堆较二项堆更为松散,除抽取最小元素和删除操作,其他操作的平摊时间复杂度在O(1)

a.斐波那契堆与二项堆的异同:

同:1、都是由有序树构成。2、每棵有序树均具有最小堆性质。3.斐波那契堆中的树不一定是二项树

异:1、斐波那契堆无论是有序树之间,还是有序树孩子均是由双向循环链表串联起来,已达到插入等操作的O(1)。2、斐波那契堆中,各棵树的度可以有重叠,并且并不需要像二项堆那样按度的大小对二项树进行排列。3、斐波那契堆的插入并不像二项堆那样,插入一个节点就合并一次,为减小频繁合并的消耗,斐波那契堆把合并操作推迟到删除一个节点时再做。4、斐波那契堆的根节点就是关键字最小的节点,而不是像二项堆那样根节点是度数最小(大)的节点

b.存储模型

struct Node
{
	Node *lbother;
	Node *rbother;
	Node *parent;
	Node *child;
	int key;
	int degree;
	bool mark;//是否被删除过孩子
	Node(int x):key(x),degree(0),mark(false),lbother(NULL),rbother(NULL),parent(NULL),child(NULL){} 
};
struct Heap
{
	int n;//堆中节点个数	
	Node *min;//最小节点,同时作为根节点 
	Heap():min(NULL),n(0){}
};
环形双链表的两个好处:1、可以在O(1)的时间内删除某个节点;2、也可以在O(1)的时间内插入某个节点。

mark标记的作用是用来标记“该节点的子节点是否有被删除过”,它的作用是来实现级联剪切。而级联剪切的真正目的是为了防止'最小堆'由树演化成链表(无节制的删孩子,删的只剩一个时,就成了链表)。

c.斐波那契堆的插入、删除、合并等

斐波那契堆代码不是自己编的来自:http://dsqiu.iteye.com/blog/1714961

//说明:
//代码中Fibonacci Heap 用变量heap表示
//结点通常用x,y等表示
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<climits>
using namespace std;
 
//斐波那契结点ADT
struct FibonacciHeapNode {
    int key;       //结点
    int degree;    //度
    FibonacciHeapNode * left;  //左兄弟
    FibonacciHeapNode * right; //右兄弟
    FibonacciHeapNode * parent; //父结点
    FibonacciHeapNode * child;  //第一个孩子结点
    bool marked;           //是否被删除第1个孩子
};
 
typedef FibonacciHeapNode FibNode;
 
//斐波那契堆ADT
struct FibonacciHeap {
    int keyNum;   //堆中结点个数
    FibonacciHeapNode * min;//最小堆,根结点
    int maxNumOfDegree;   //最大度
    FibonacciHeapNode * * cons;//指向最大度的内存区域
};
 
typedef FibonacciHeap FibHeap;
 
/*****************函数申明*************************/
//将x从双链表移除
inline void FibNodeRemove(FibNode * x);
 
//将x堆结点加入y结点之前(循环链表中)
void FibNodeAdd(FibNode * x, FibNode * y);
 
//初始化一个空的Fibonacci Heap
FibHeap * FibHeapMake() ;
 
//初始化结点x
FibNode * FibHeapNodeMake();
 
//堆结点x插入fibonacci heap中
void FibHeapInsert(FibHeap * heap, FibNode * x);
 
//将数组内的值插入Fibonacci Heap
void FibHeapInsertKeys(FibHeap * heap, int keys[], int keyNum);
 
//将值插入Fibonacci Heap
static void FibHeapInsertKey(FibHeap * heap, int key);
 
//抽取最小结点
FibNode * FibHeapExtractMin(FibHeap * heap);
 
//合并左右相同度数的二项树
void FibHeapConsolidate(FibHeap * heap);
 
//将x根结点链接到y根结点
void FibHeapLink(FibHeap * heap, FibNode * x, FibNode *y);
 
//开辟FibHeapConsolidate函数哈希所用空间
static void FibHeapConsMake(FibHeap * heap);
 
//将堆的最小结点移出,并指向其有兄弟
static FibNode *FibHeapMinRemove(FibHeap * heap);
 
//减小一个关键字
void FibHeapDecrease(FibHeap * heap, FibNode * x, int key);
 
//切断x与父节点y之间的链接,使x成为一个根
static void FibHeapCut(FibHeap * heap, FibNode * x, FibNode * y);
 
//级联剪切
static void FibHeapCascadingCut(FibHeap * heap, FibNode * y);
 
//修改度数
void renewDegree(FibNode * parent, int degree);
 
//删除结点
void FibHeapDelete(FibHeap * heap, FibNode * x);
 
//堆内搜索关键字
FibNode * FibHeapSearch(FibHeap * heap, int key);
 
//被FibHeapSearch调用
static FibNode * FibNodeSearch(FibNode * x, int key);
 
//销毁堆
void FibHeapDestory(FibHeap * heap);
 
//被FibHeapDestory调用
static void FibNodeDestory(FibNode * x);
 
//输出打印堆
static void FibHeapPrint(FibHeap * heap);
 
//被FibHeapPrint调用
static void FibNodePrint(FibNode * x);
/************************************************/
 
//将x从双链表移除
inline void FibNodeRemove(FibNode * x) {
    x->left->right = x->right;
    x->right->left = x->left;
}
 
/*
将x堆结点加入y结点之前(循环链表中)
    a …… y
    a …… x …… y
*/
inline void FibNodeAdd(FibNode * x, FibNode * y) {
    x->left = y->left;
    y->left->right = x;
    x->right = y;
    y->left = x;
}
 
//初始化一个空的Fibonacci Heap
FibHeap * FibHeapMake() {
    FibHeap * heap = NULL;
    heap = (FibHeap *) malloc(sizeof(FibHeap));
    if (NULL == heap) {
        puts("Out of Space!!");
        exit(1);
    }
    memset(heap, 0, sizeof(FibHeap));
    return heap;
}
 
//初始化结点x
FibNode * FibHeapNodeMake() {
    FibNode * x = NULL;
    x = (FibNode *) malloc(sizeof(FibNode));
    if (NULL == x) {
        puts("Out of Space!!");
        exit(1);
    }
    memset(x, 0, sizeof(FibNode));
    x->left = x->right = x;
    return x;
}
 
//堆结点x插入fibonacci heap中
void FibHeapInsert(FibHeap * heap, FibNode * x) {
    if (0 == heap->keyNum) {
        heap->min = x;
    } else {
        FibNodeAdd(x, heap->min);
        x->parent = NULL;
        if (x->key < heap->min->key) {
            heap->min = x;
        }
    }
    heap->keyNum++;
}
 
//将数组内的值插入Fibonacci Heap
void FibHeapInsertKeys(FibHeap * heap, int keys[], int keyNum) {
    for (int i = 0; i < keyNum; i++) {
        FibHeapInsertKey(heap, keys[i]);
    }
}
 
//将值插入Fibonacci Heap
static void FibHeapInsertKey(FibHeap * heap, int key) {
    FibNode * x = NULL;
    x = FibHeapNodeMake();
    x->key = key;
    FibHeapInsert(heap, x);
}
 
//抽取最小结点
FibNode * FibHeapExtractMin(FibHeap * heap) {
    FibNode * x = NULL, * z = heap->min;
    if (z != NULL) {
 
        //删除z的每一个孩子
        while (NULL != z->child) {
            x = z->child;
            FibNodeRemove(x);
            if (x->right == x) {
                z->child = NULL;
            } else {
                z->child = x->right;
            }
            FibNodeAdd(x, z);//add x to the root list heap
            x->parent = NULL;
        }
 
        FibNodeRemove(z);
        if (z->right == z) {
            heap->min = NULL;
        } else {
            heap->min = z->right;
            FibHeapConsolidate(heap);//合并两个度相同的树
        }
        heap->keyNum--;
    }
    return z;
}
 
//合并左右相同度数的二项树
void FibHeapConsolidate(FibHeap * heap) {
    int D, d;
    FibNode * w = heap->min, * x = NULL, * y = NULL;
    FibHeapConsMake(heap);//开辟哈希所用空间
    D = heap->maxNumOfDegree + 1;
    for (int i = 0; i < D; i++) {
        *(heap->cons + i) = NULL;
    }
 
    //合并相同度的根节点,使每个度数的二项树唯一
    while (NULL != heap->min) {
        x = FibHeapMinRemove(heap);
        d = x->degree;
        while (NULL != *(heap->cons + d)) {
            y = *(heap->cons + d);
            if (x->key > y->key) {//根结点key最小
                swap(x, y);
            }
            FibHeapLink(heap, y, x);
            *(heap->cons + d) = NULL;
            d++;
        }
        *(heap->cons + d) = x;
    }
    heap->min = NULL;//原有根表清除
 
    //将heap->cons中结点都重新加到根表中,且找出最小根
    for (int i = 0; i < D; i++) {
        if (*(heap->cons + i) != NULL) {
            if (NULL == heap->min) {
                heap->min = *(heap->cons + i);
            } else {
                FibNodeAdd(*(heap->cons + i), heap->min);
                if ((*(heap->cons + i))->key < heap->min->key) {
                    heap->min = *(heap->cons + i);
                }//if(<)
            }//if-else(==)
        }//if(!=)
    }//for(i)
}
 
//<辅助函数>将x根结点链接到y根结点
void FibHeapLink(FibHeap * heap, FibNode * x, FibNode *y) {
    FibNodeRemove(x);
    if (NULL == y->child) {
        y->child = x;
    } else {
        FibNodeAdd(x, y->child);
    }
    x->parent = y;
    y->degree++;
    x->marked = false;
}
 
//<辅助函数,c++中可以用map代替>开辟FibHeapConsolidate函数哈希所用空间
static void FibHeapConsMake(FibHeap * heap) {
    int old = heap->maxNumOfDegree;
    heap->maxNumOfDegree = int(log(heap->keyNum * 1.0) / log(2.0)) + 1;
    if (old < heap->maxNumOfDegree) {
        //因为度为heap->maxNumOfDegree可能被合并,所以要maxNumOfDegree + 1
        heap->cons = (FibNode **) realloc(heap->cons,
            sizeof(FibHeap *) * (heap->maxNumOfDegree + 1));
        if (NULL == heap->cons) {
            puts("Out of Space!");
            exit(1);
        }
    }
}
 
//<辅助函数>将堆的最小结点移出,并指向其有兄弟
static FibNode *FibHeapMinRemove(FibHeap * heap) {
    FibNode *min = heap->min;
    if (heap->min == min->right) {
        heap->min = NULL;
    } else {
        FibNodeRemove(min);
        heap->min = min->right;
    }
    min->left = min->right = min;
    return min;
}
 
//减小一个关键字
void FibHeapDecrease(FibHeap * heap, FibNode * x, int key) {
    FibNode * y = x->parent;
    if (x->key < key) {
        puts("new key is greater than current key!");
        exit(1);
    }
    x->key = key;
 
    if (NULL != y && x->key < y->key) {
        //破坏了最小堆性质,需要进行级联剪切操作
        FibHeapCut(heap, x, y);
        FibHeapCascadingCut(heap, y);
    }
    if (x->key < heap->min->key) {
        heap->min = x;
    }
}
 
//切断x与父节点y之间的链接,使x成为一个根
static void FibHeapCut(FibHeap * heap, FibNode * x, FibNode * y) {
    FibNodeRemove(x);
    renewDegree(y, x->degree);
    if (x == x->right) {
        y->child = NULL;
    } else {
        y->child = x->right;
    }
    x->parent = NULL;
    x->left = x->right = x;
    x->marked = false;
    FibNodeAdd(x, heap->min);
}
 
//级联剪切
static void FibHeapCascadingCut(FibHeap * heap, FibNode * y) {
    FibNode * z = y->parent;
    if (NULL != z) {
        if (y->marked == false) {
            y->marked = true;
        } else {
            FibHeapCut(heap, y, z);
            FibHeapCascadingCut(heap, z);
        }
    }
}
 
//修改度数
void renewDegree(FibNode * parent, int degree) {
    parent->degree -= degree;
    if (parent-> parent != NULL) {
        renewDegree(parent->parent, degree);
    }
}
 
//删除结点
void FibHeapDelete(FibHeap * heap, FibNode * x) {
    FibHeapDecrease(heap, x, INT_MIN);
    FibHeapExtractMin(heap);
}
 
//堆内搜索关键字
FibNode * FibHeapSearch(FibHeap * heap, int key) {
    return FibNodeSearch(heap->min, key);
}
 
//被FibHeapSearch调用
static FibNode * FibNodeSearch(FibNode * x, int key) {
    FibNode * w = x, * y = NULL;
    if (x != NULL) {
        do {
            if (w->key == key) {
                y = w;
                break;
            } else if (NULL != (y = FibNodeSearch(w->child, key))) {
                break;
            }
            w = w->right;
        } while (w != x);
    }
    return y;
}
 
//销毁堆
void FibHeapDestory(FibHeap * heap) {
    FibNodeDestory(heap->min);
    free(heap);
    heap = NULL;
}
 
//被FibHeapDestory调用
static void FibNodeDestory(FibNode * x) {
    FibNode * p = x, *q = NULL;
    while (p != NULL) {
        FibNodeDestory(p->child);
        q = p;
        if (p -> left == x) {
            p = NULL;
        } else {
            p = p->left;
        }
        free(q->right);
    }
}
 
//输出打印堆
static void FibHeapPrint(FibHeap * heap) {
    printf("The keyNum = %d\n", heap->keyNum);
    FibNodePrint(heap->min);
    puts("\n");
};
 
//被FibHeapPrint调用
static void FibNodePrint(FibNode * x) {
    FibNode * p = NULL;
    if (NULL == x) {
        return ;
    }
    p = x;
    do {
        printf(" (");
        printf("%d", p->key);
        if (p->child != NULL) {
            FibNodePrint(p->child);
        }
        printf(") ");
        p = p->left;
    }while (x != p);
}
 
int keys[10] = {1, 2, 3, 4, 5, 6, 7, 9, 10, 11};
 
int main() {
    FibHeap * heap = NULL;
    FibNode * x = NULL;
    heap = FibHeapMake();
    FibHeapInsertKeys(heap, keys, 10);
    FibHeapPrint(heap);
 
    x = FibHeapExtractMin(heap);
    printf("抽取最小值%d之后:\n", x->key);
    FibHeapPrint(heap);
 
    x = FibHeapSearch(heap, 11);
    if (NULL != x) {
        printf("查找%d成功,", x->key);
        FibHeapDecrease(heap, x, 8);
        printf("减小到%d后:\n", x->key);
        FibHeapPrint(heap);
    }
 
    x = FibHeapSearch(heap, 7);
    if (NULL != x) {
        printf("删除%d成功:\n", x->key);
        FibHeapDelete(heap, x);
        FibHeapPrint(heap);
    }
 
    FibHeapDestory(heap);
    return 0;
}

4.用于不相交集合的数据结构

其实就是并查集,链表形式不再给出,非链表形式,参见树基础总结:http://blog.csdn.net/chinajane163/article/details/49468737


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值