优先队列(堆)

Posted Lunais

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了优先队列(堆)相关的知识,希望对你有一定的参考价值。

在打印机作业时一般采用队列的形式FIFO(fisrt in first out),但遇到一个1份的和一个100份的作业时,先打印1份的相对合理;另外,不同作业的优先级也不同,优先级高的应该先处理。

 insert == Enqueue

deleteMin == Dequeue

二叉堆(完全二叉树):除了底层,一棵被完全填满的二叉树,底层上元素从左到右填入。

完全二叉树很有规律,可用数组表示:对于任一节点元素X,其父节点元素H->element[i/2],其左儿子H->element[2i],右儿子H->element[2i+1]。

  A B C D E F G H I  J  

0 1 2 3 4 5 6 7 8 9 10 11 12 13 

一个堆的数据结构:一个数组、容量、当前堆大小。

注意事项:

 

节点声明:

struct heap
{
       int           capacity;
       int           size;
       elementType   *elements;
}

堆序性:节点X的关键字 大于等于  节点X父亲节点的关键字。

priority queue creat:

priorityQueue *initialize( int maxElement)
{
       priotityQueue *H;
       if (maxElement < minPQSize)
       {
             cout << "priorityQueue is too small" << endl;
             return NULL;
       } 
       H->elements = New element[maxElement + 1];
       if(H->elements == NULL)
       {
             cout << "out of space" << endl;
             return NULL;
       }
       H->capacity = maxElement;
       H->size = 0;
       H->elements[0] = minData; //minData为足够小的数,保证元素插入后最多上滤到i=1处,即根节点。
       return H; 
}

 insert:(末端插入)

void insert (elementType X , PriotityQueue *H)
{
       if (isFull (H))
       {
           cout<< "out of space" << endl;
           return;
       }
       for(int i = ++H->size; X < H->elements[i/2]; i/=2)  // H->elements[0]是一个足够小的数minData,保证X<minData不成立。
       H->elements[i] = H->elements[i/2];
       H->elements[i] = X;
}

 deleteMin(根处删除)

elementType deleteMin(priorityQueue *H)
{
       int child;
       elementType minElement , lastElement;

       if(isEmpty(H))
       {
             cout << "priotityQueue is empty" << endl;
             return H->elements[0];
       }
       minElement = H->elements[1];
       lastElement = H->elements[H->size--];//保存最后一个元素,size-1
          
       for( int i = 1; 2*i <= H->size; i = child)
       {
             child = 2*i;
             if(child != H->size && H->element[child + 1] < H->element[child])
                child++;
             if(H->element[child]<lastElement)
                H->element[i] = H->element[child];
             else 
                break;
       }
       H->elements[i] = lastElement;
       return minElement;
}

 

以上是关于优先队列(堆)的主要内容,如果未能解决你的问题,请参考以下文章

用分解的方式学算法006——堆排序

学习数据结构基础

POJ3784 动态中位数(大根堆+小根堆+优先队列)

优先队列学习随记

如何在实现为二进制堆的优先级队列中保留相同优先级元素的顺序?

[剑指offer] 41. 数据流中的中位数 (大小堆,优先队列)