mysql 优先队列,优先队列(堆) - passionfly的个人空间 - OSCHINA - 中文开源技术交流社区...

一、优先队列的一些简单的实现:

1. 使用一个简单的链表在表头以O(1) 执行插入操作,并遍历该链表以删除最小元,这需要O(N) 的时间。

2. 始终让表保持有序状态;这使得插入代价高昂(O(N)), 而删除代价低廉(O(1))。基于删除最小元的操作从不多于插入操作的事实,因此,前者是更好地想法。

3. 使用二叉查找树,它对这两种操作的平均运行时间是O(logN)。尽管插入是随机的,而删除不是,但这个结论还是成立的。由于删除的唯一元素是最小元。反复除去左子树中的节点似乎损害树的平衡,使得右子树加重。然而,右子树是随机的。在最坏的情形,即将左子树删空的情形,右子树拥有的元素最多。(查找树中有许多并不需要的操作)

4. 将要使用的工具二叉堆(堆):它的使用对于优先队列的实现是如此的普遍。

二、 堆具有两个性质:结构性质和堆序性质

1)结构性质:堆是一棵被完全填满的二叉树,有可能的例外是在底层,底层上的元素从左到右填入,即为:一棵完全二叉树。

一棵高为 h 的完全二叉树的节点数为 2^h ~ 2^(h+1)-1。这意味着完全二叉树是O(logN)。

因为完全二叉树很有规律,所以它可以用一个数组表示,而不使用指针。对数组中任意位置 i 上的元素,其左孩子在 2i 位置处,右孩子在左孩子的后一单元(2i+1)中,它的父节点在 i / 2(下取整) 上。这种实现唯一的问题在于,最大的堆大小需要事先估计,但对于典型的情况这并不成问题。

因此,一个堆的数据结构将由一个数组(不管关键字是什么类型)、一个代表最大值的整数,以及当前的堆大小组成。

#define MINQUSIZE 5

#define MinData 0.0001

typedef int ElemType;

typedef struct HeapStruct

{

ElemType *elem;

int Capasity;

int Size;

}Heap, *PriorityQueue;

2)堆序性质:使操作被快速执行的性质是堆序性,由于要快速的找出最小元,因此,最小元应该在根上。考虑任意子树也应该是一个堆,那么仁义节点应该小于它的所有后裔。

在一个堆中,对于每一个节点X, X的父亲中的关键字小于(或等于)X 中的关键字,根节点除外(它没有父亲)。

三、基本操作:

1)插入(Insert):为将一个元素X 插入堆中,我们在下一个空闲位置(数组末尾)创建一个空穴,否则,该堆就不是完全树。如果X 可以放在空穴中,而并不破坏堆的序,那么插入完成。否则,将空穴的父节点上的元素放入空穴中,这样空穴的位置就朝着跟的方向上移一个位置。继续该过程直至 X 能被放入空穴中为止。这一操作称之为上滤。

void InsertHeap(ElemType value, PriorityQueue H)

{

int i;

if(H->Size == H->Capasity) //堆已满

return;

for(i = ++H->Size; H->elem[i / 2] > value; i /= 2)

{

H->elem[i] = H->elem[i / 2];  //父节点下移

}

H->elem[i] = value;

}

2) 删除操作(DeleteMin):删除最小元。当删除最小元时,在根节点处产生了一个空穴。由于现在堆少了一个元素,因此堆中最后一个元素 X 必须移动到该堆的某个位置。如果 X 可以被放到空穴中,那么删除操作完成。这一般不太可能完成,因此,将空穴的两个儿子中较小的一个移入空穴,这样就把空穴向下推了一层。重复该步骤直到 X 可以被放入空穴中。因此,我们的做法是将 X 置入从根开始包含最小儿子的一条路径上的一个正确位置。

ElemType DeleteMin(PriorityQueue H)

{

int i, child;

ElemType MinElem, LastElem;

if(H->Size == 0)

{

cout <

return H->elem[0];

}

//堆的建立

#include

#define MINQUSIZE 5

#define MinData 0.0001

using namespace std;

typedef int ElemType;

typedef struct HeapStruct

{

ElemType *elem;

int Capasity;

int Size;

}Heap, *PriorityQueue;

PriorityQueue InitializeHeap(int MaxSize)

{

PriorityQueue H;

if (MaxSize 

throw("Priority queue size is too small.");

H = new HeapStruct();

H->elem = new int[MaxSize + 1];

H->Capasity = MaxSize;

H->Size = 0;

H->elem[0] = MinData;

return H;

}

void InsertHeap(ElemType value, PriorityQueue H)

{

int i;

if(H->Size == H->Capasity) //堆已满

return;

for(i = ++H->Size; H->elem[i / 2] > value; i /= 2)

{

H->elem[i] = H->elem[i / 2];  //父节点下移

}

H->elem[i] = value;

}

ElemType DeleteMin(PriorityQueue H)

{

int i, child;

ElemType MinElem, LastElem;

if(H->Size == 0)

{

cout <

return H->elem[0];

}

MinElem = H->elem[1];

LastElem = H->elem[H->Size--];

for(i = 1; i *2 <= H->Size; i = child)

{

child = i * 2; //i 的左孩子

if(child != H->Size && H->elem[child] > H->elem[child + 1])

child++;

if(LastElem > H->elem[child])

H->elem[i] = H->elem[child]; //空穴下移

else

break;

}

H->elem[i] = LastElem;

return MinElem;

}

int main()

{

PriorityQueue H;

H = InitializeHeap(10);

for(int i = 1; i 

InsertHeap(i, H);

for(int j = 0; j <= H->Size; j++)

cout <elem[j] <

cout <

DeleteMin(H);

for(int j = 0; j <= H->Size; j++)

cout <elem[j] <

system("pause");

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值