首页 > 代码库 > 优先队列

优先队列

许多应用程序都需要处理有序的元素,但不一定要求全部有序。一个合适的数据结构应该支持两种操作:删除最大元素和插入元素。

 1 #include <iostream> 2 #include <queue> 3 using namespace std; 4  5  6 struct node 7 { 8     int priority; 9     int value;10     friend bool operator<(node n1, node n2)11     {12         return n1.priority < n2.priority;13     }14 };15 16 17 struct cmp18 {19     bool operator() (const int &a, const int &b)20     {21         return a > b;22     }23 };24 25 int main()26 {27     // Use 128     cout << "Use 1" << endl;29     priority_queue<int> qi;30     qi.push(10);31     qi.push(78);32     qi.push(13);33     qi.push(12);34     qi.push(50);35 36     // expect output is 78 50 13 12 1037     while(!qi.empty())38     {39         cout << qi.top() << endl;40         qi.pop();41     }42 43     // Use 244     cout << "Use case 2"<<endl;45     priority_queue<int, vector<int>, less<int> > qi2;46     qi2.push(10);47     qi2.push(78);48     qi2.push(13);49     qi2.push(12);50     qi2.push(50);51 52     // expect output is 78 50 13 12 1053     while(!qi2.empty())54     {55         cout << qi2.top() << endl;56         qi2.pop();57     }58     int a;59     cin >> a;60     return 0 ;61 }
View Code

以上代码是C++自带的优先队列,我们可以知道:
void push(T value); 向优先队列中插入一个元素

T Top(); 返回最大元素

void Pop(); 删除最大元素

那他是如何实现的呢?我们可以选择数组实现,也可以选择链表实现,也可以每次增加一个元素的时候都确保元素有序(积极),也可以保持无序状态,在调用Top时寻找最大的值(懒惰),除此之外我们可以使用堆这种数据结构来实现。

堆的定义:二叉堆就是一棵完全二叉树。

对于给定的某个节点的下标i,我们有以下公式:

Parent(i) = Floor(i/2)

Left(i) = 2i

Right(i) = 2i + 1

 

 

前提: pq[0...N+1] pq[0] 未使用, 一共N个数

比较和交换的方法:

private boolean less(int i , int j){return pq[i].CompareTo(pq[j]) < 0;}private void exch(int i, int j){Key t = pq[i]; pq[i] = pq[j]; pq[j] = t;}

 


由下至上的堆有序化 (上浮)

private void swim(int k)

{

while(k > 1 && less(k/2,k))

{

exch(k, k/2);

k = k/2;

}

}

 由上至下的堆有序化(下沉)

private void sink(int k)

{

while(2*k <= N)

{

int j = 2*k;

// Get the max value for left and right child

if(j < N && !less(j, j+1)) j++;

if(!less(k, j)) break;

exch(k, j);

k = j;

}

}

有了这些基本函数后,我们就可以实现, push/pop了

push(插入元素):我们将新增的元素加到数组末尾,增加堆的大小并使之上浮到合适位置

pop(删除元素):我们从数组顶端删去最大的元素并将数组的最后一个元素放到顶端,减小堆的大小并下层到合适位置

 

public void push(Key v){ pq[++N] = v; swim(N);}public Key top(){}

 

 

http://www.cnblogs.com/kkun/archive/2011/11/23/2260286.html