您的位置:首页 > 其它

堆的操作的复杂度

2016-03-05 11:41 225 查看
堆的两种操作所花的时间都和树的深度成正比.因此,如果一共有n个元素,那么每个操作可以在O(logn)时间内完成.

堆的实现

1.左儿子的编号是自己的编号*2+1

2.右儿子的编号是自己的编号*2+1

push和pop的实现:

int heap[MAX],sz=0;

void push(int x)
{
//自己节点的编号
int i=sz++;

while(i>0){
//父亲节点的编号
int p=(i-1)/2;

//如果已经没有大小颠倒则退出
if(heap[p]<=x) break;

//把父亲节点的数值放下来,而把自己提上去
heap[i]=heap[p];
i=p;
}
}

int pop()
{
//最小值
int ret=heap[0];

//要提到根的数值
int x=heap[--sz];

//从根开始向下交换
int i=0;
while(i*2+1<sz){
//比较儿子的值
int a=i*2+1,n=i*2+2;
if(b<sz && heap[b]<heap[a])  a=b;

//如果已经没有大小颠倒则退出
if(heap[a]>=x)
break;

//把儿子的数组提上来
heap[i]=heap[a];
i=a;
}
heap[i]=x;
return ret;
}


编程语言的标准库:

实际上,大部分情况并不需要自己实现堆.在许多编程语言的标准中,都包含了优先队列的高效实现.例如在c++中,STL里的priority_queue就是其中之一.不过需要注意的是,priority_queue与上面讲的优先队列有所不同,取出数值得到的是最大值.

#include <queue>
#include <cstdio>
using namespace std;

int main()
{
//声明
priority_queue<int> p;

//插入元素
p.push(3);
p.push(5);
p.push(1);

//不断循环直到空为止
while(!p.empty()){
//获取并删除最大值
printf("%d\n",p.top());
p.pop();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: