标签:style io color os ar 使用 for sp strong
一、优先队列的一些简单的实现:
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 << "PriorityQueue is empty." << endl;
return H->elem[0];
}
//堆的建立 #include<iostream> #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 < MINQUSIZE) 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 << "PriorityQueue is empty." << endl; 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 < 8; i++) InsertHeap(i, H); for(int j = 0; j <= H->Size; j++) cout << H->elem[j] << " "; cout << endl; DeleteMin(H); for(int j = 0; j <= H->Size; j++) cout << H->elem[j] << " "; system("pause"); return 0; }
标签:style io color os ar 使用 for sp strong
原文地址:http://my.oschina.net/u/2260265/blog/339811