堆以及堆的相关应用
来源:互联网 发布:做flash的软件 编辑:程序博客网 时间:2024/06/01 10:21
堆简介:
本文中的堆是一种树形数据结构,可以把堆看成一种特殊的完全二叉树,再从二叉树上加上一些限制条件即可以构成堆。即要求父节点元素全部都大于或等于子节点元素,或者小于等于。
这就构成了俩种堆:
1.大根堆:A[PARENT[i]] >= A[i]
2.小根堆:A[PARENT[i]] <= A[i]
堆的常见应用为:
- 使用堆进行排序,也就是常说的堆排序,时间复杂度为nlgn(这是比较排序时间复杂度的下限,即使用比较的排序方法,时间复杂度不可能比这个更低了)。其具体的做法是利用大根堆(假设此时堆的元素个数尾heapsize-1),每次把堆顶元素和堆尾元素表交换,那么最大的元素就再堆尾了,这就算确定了一个元素的最终位置,然后再把新的包含heapsize-1个元素的堆进行位置调整,因为之前的调换有可能破坏的堆。这个过程迭代到堆元素为0即结束,此时元素已经排序好了。
实现最大优先队列,优先队列是一种用来维护元素构成集合S的数据结构,一个最大优先队列支持一下操作
1.insert(S,x) 把x插入结合S
2.maxmum(S),返回S中关键字最大的元素
3.Extractmax(S),返回并且删除S中关键字最大的元素。
4.incresment-key(S,x,k),把元素x的关键字增加到k,这里假设k不小于x的原关键字值。 最大优先队列的应用很多,其中一个就是共享计算机的作业调度,对打优先队列记录各个作业之间的优先级,当一个作业完成或者被中断时,调用extreacmax从等待作业中选出优先级最高的执行,在任何时候都可以调用insert来插入一个作业。实现最小优先队列,主要用在事件调度的模拟器。
说完了堆的基本概念和应用,下面我们来看你看堆具体怎么实现。
再次我们用数组实现堆,首先再一棵二叉树中加入根的位置是i(数组从1开始,0号单元不用)那门其左子输的位置就为2×i,右子树的位置为2×i+1.其父节点的位置就为i/2.把这些关系写成函数有:
int parent(int i){ //得到节点i的父节点
return i/2;
}
int right(int i){ //得到节点i左孩子
return 2*i+1;
}
int left(int i){ //得到节点i的右孩子
return 2*i;
}
我们把建堆的步骤分解:
- max_heap维护堆的性质。
给定一个节点A[i]找出其左右子节点和A[i]三个数的最大值,把A[i]和最大值调换,对于调换过的节点,递归实现此过程。 - build_max_heap从后往前维护堆的性质,当这个过程完成以后,整个堆就建立了。
对所有非叶子节点实现max_heap过程即可建立一个堆。 下面给出堆排序具体实现其中包含了建堆以及排序:
#include<stdio.h>int parent(int i){ return i/2;}int right(int i){ return 2*i+1;}int left(int i){ return 2*i;}int heapsize=10;//维护堆的性质void max_heap(int A[],int i,int heapsize){ int l=left(i); int r=right(i); int largest=i; if(l<=heapsize&&A[l]>A[i]) largest=l; if(r<=heapsize&&A[r]>A[largest]) largest=r; if(largest!=i){ int temp=A[i]; A[i]=A[largest]; A[largest]=temp; max_heap(A,largest,heapsize);}}//建堆,从len/2以后的位置节点均为子节点,而且必须从后往前建堆即从//len/2--->1void build_max_heap(int A[],int len){ int i=0; for(i=len/2;i>=1;i--){ max_heap(A,i,len);}}//每次取最大的放在最后,剩下的调整位置成为一个新的堆void heap_sort(int A[],int heapsize){ while(heapsize>=1){ int temp=0; temp=A[heapsize]; A[heapsize]=A[1]; A[1]=temp; heapsize--; max_heap(A,1,heapsize);}}int main(){ int len=10; int A[]={0,2,3,6,2,16,9,10,14,8,7}; build_max_heap(A,10); heap_sort(A,heapsize); int i=0; for(i=1;i<=len;i++) printf("%d ",A[i]); printf("\n"); return 0;}
下面给出最大优先队列实现代码:
#include<stdio.h>#include<malloc.h>typedef struct Heap{ //定义一个堆数据结构,主要为了封装heapsize int data[20]; int heapsize;}heap;int parent(int i){ return i/2;}int left(int i){ return 2*i;}int right(int i){ return 2*i+1;}//保持堆的性质void max_heap(heap *A,int i){ int l=left(i); int r=right(i); int largest=i; if(l<=A->heapsize&&A->data[l]>A->data[largest]){ largest=l; } if(r<=A->heapsize&&A->data[r]>A->data[largest]){ largest=r; } if(i!=largest){ int temp; temp=A->data[i]; A->data[i]=A->data[largest]; A->data[largest]=temp; max_heap(A,largest); }}void build_max_heap(heap* A){ //建堆 int i=0; for(i=(A->heapsize)/2;i>=1;i--){ max_heap(A,i); }}int heap_maxmun(heap *A){ //return the max value return A->data[1];}int heap_extract_max(heap *A){ //return and remove max value int temp=0; temp=A->data[A->heapsize]; A->data[A->heapsize]=A->data[1]; A->data[1]=temp; max_heap(A,1); A->heapsize--; return A->data[A->heapsize+1];}void heap_incresment_key(heap *A,int i,int key){ if(A->data[i]>key) return; A->data[i]=key; while (i>1&&A->data[parent(i)]<A->data[i]) { int temp=A->data[i]; A->data[i]=A->data[parent(i)]; A->data[parent(i)]=temp; i=parent(i); }}void heap_max_heap_insert(heap *A,int key){ A->heapsize++; A->data[A->heapsize]=0; heap_incresment_key(A,A->heapsize,key);}int main(){ heap* A=(heap*)malloc(sizeof(heap)); int i=0; for(i=0;i<=10;i++){ A->data[i]=i; }// A.data={0,1,2,3,4,5,6,7,8,9,10}; A->heapsize=10; build_max_heap(A); for(i=1;i<=A->heapsize;i++){ printf("%d ",A->data[i]); } printf("\n"); printf("%d",heap_extract_max(A)); printf("\n"); heap_max_heap_insert(A,10); heap_incresment_key(A,3,11); for(i=1;i<=A->heapsize;i++) printf("%d ",A->data[i]); printf("\n");}
- 堆以及堆的相关应用
- 堆的应用:topk问题以及堆排序
- 堆排序,以及stl中的堆应用
- 堆的相关算法
- 堆的相关知识
- 堆的相关操作
- 堆的相关知识
- 【算法】堆排序以及应用
- 堆的构建以及利用堆排序
- 堆数据结构的实现以及堆排序
- 堆的简述以及堆排序
- 堆的概念以及实现堆
- 堆的简介以及堆排序
- 堆的应用
- 【算法】堆的应用
- 堆的应用
- 【poj3253】堆的应用
- 【数据结构】堆的应用
- 带checkbox的listView 实现多选,全选,反选
- java之nslookup小程序--查询IP地址以及对应域名
- 黑马程序员-C语言回顾-运算符
- 设计模式系列(三)装饰者模式(Decorator Pattern)
- 几何-线和角
- 堆以及堆的相关应用
- 分离链接散列表
- Trie树------一种NB的数据结构
- 打僵尸代码
- Object-C,数组NSArray
- LinearLayout 属性详解
- 日经春秋 20151201
- 趣味取小数
- proteus7.8破解版安装tips