本文主要复习优先队列的相关知识。运用二叉堆数据结构实现优先处理队列中的较小元素(当然也可以是其他的元素)。所谓二叉堆,其几何形状就是完全二叉树。这样的话,我们就可以用数组来实现二叉堆,原因就是一个节点i的子节点就是2i和2i+1,一个节点的父节点就是i/2取整数部分。这样就避免了使用指针来寻找二叉树中的位置,加快了搜寻速度。
同时,插入和删除(包括删除之后的重新恢复二叉堆)所需要的平均时间复杂度为O(logn).
本文主要复习二叉堆中的基本操作:插入和返回并删除最小元。相关代码如下:
头文件的定义
#ifndef heap_H_
#define heap_H_
struct binary_heap;
typedef struct binary_heap *Heap;
Heap Init(int heap_cap);
void Insert(int x,Heap h);
int Deletemin(Heap h);
#endif // heap_H_
相关操作函数的定义
#include <stdio.h>
#include <stdlib.h>
#include "main.h"
#define mincap 100
#define mindata -100000
struct binary_heap
{
int *Element;
int Heapsize;
int Capacity;
};
//Init
Heap Init(int heap_cap)
{
if(heap_cap<mincap)
printf("error,the size is too small\n");
else
{
Heap h=malloc(sizeof(struct binary_heap));
h->Element=malloc(sizeof(int)*heap_cap);
h->Heapsize=0;
h->Capacity=heap_cap;
h->Element[0]=mindata;//注意,在0位置设置一个很小的值,用来在插入时做结束的判断
return h;
}
}
//Insert
void Insert(int x,Heap h)
{
if(h->Capacity==h->Heapsize)
printf("error,the heap is full\n");
else
{
int i=++h->Heapsize;//注意heapsize的自加
for(;h->Element[i/2]>x;i=i/2)
h->Element[i]=h->Element[i/2];
h->Element[i]=x;
}
}
int Deletemin(Heap h)
{
if(h->Heapsize==0)
printf("error,the heap is empty\n");
else
{
int final_tem=h->Element[h->Heapsize--];
int i=1,child;
int min_elem=h->Element[1];
while(2*i<=h->Heapsize)
{
child=2*i;
if(2*i<h->Heapsize&&h->Element[2*i]>h->Element[2*i+1])
child=child+1;
if(h->Element[child]>final_tem)
break;
else
{
h->Element[i]=h->Element[child];
i=child;
}
}
h->Element[i]=final_tem;
return min_elem;
}
}
主函数
int main()
{
Heap H=Init(200);
int i=0;
for(;i<10;i++)
Insert(i,H);
for(i=0;i<10;i++)
printf("%d",H->Element[i+1]);
printf("\n");
int min=Deletemin(H);
for(i=1;i<=H->Heapsize;i++)
printf("%d",H->Element[i]);
printf("\n");
printf("%d",min);
return 0;
}
在做插入操作时,插入的最坏时间高达
O(logN)
,这在欲插入的元素是新的最小元素时发生,但是实际终止的时间要早,执行一次插入平均需要2.607次,也就是说插入所需的平均时间是
O(1)
.
在做删除最小值操作时,最坏的时间复杂为
O(logN)
,平均时间复杂度为
O(logN)