标签:优先队列
简介
优先队列:指队列中的元素都被指派一个优先级,元素按优先级最大(最小)出队,存储堆的数组的第一个元素就是最大的(或最小的)。所以用堆作为优先队列的元素载体是合适的。
队列有两个基本操作:1.入队2.出队。
队列的特点是先进先出。通常都把队列比喻成排队买东西,大家都很守秩序,先排队的人就先买东西。但是优先队列有所不同,它不遵循先进先出的规则,而是根据队列中元素的优先权,优先权最大的先被取出。通常把优先队列比喻成现实生活中的打印。一个打印店里有很多打印机,每台机器的性能不一样,有的打印机打印很快,有的打印机打印速度很慢。当这些打印机陆陆续续打印完自己的任务时进入排队等候状态。如果我这个时候要打印一份文件,我选的不是第一个排队的打印机,而是性能最好,打印最快的打印机。
重点:优先级队列,是要看优先级的,谁的优先级更高,谁就先得到权限。不分排队的顺序!
基本操作:
empty() 如果队列为空返回真
pop() 删除对顶元素
push() 加入一个元素
size() 返回优先队列中拥有的元素个数
top() 返回优先队列对顶元素
在默认的优先队列中,优先级高的先出队。在默认的int型中先出队的为较大的数。
代码实现(c语言)
#include<stdlib.h>
#include <string.h>
#include <assert.h>
#include "queen.h"
#include "swap.h"
#include "heap.h"
priorityQueen heapAlloc(int size, int n)
{
priorityQueen q;
q.length = n;//设置堆的最大长度
q.heapsize = 0;//目前堆为空、
q.heap = (void*)malloc(n*size);//分配堆空间
return q;
}
/***************入队操作*************************
size: 单个元素所占字长
q: 队列
e:入队元素
comp:比较函数(适应最大或最小堆)
************************************************/
void enQueen(priorityQueen*q, int size, void *e, int(*compare)(void*, void*))
{
if (q->heapsize == q->length)//队列满
return;
int i = q->heapsize++;//i为扩大后的堆的最后元素的下标
memcpy((char*)(q->heap) + i*size, e, size);//heap[i]<--e
while (i>0 && compare((char*)(q->heap) + parent(i)*size, (char*)(q->heap) + i*size)<0)//parent(i)<heap[i],其大于或小于父节点
{
swap((char*)(q->heap) + parent(i)*size, (char*)(q->heap) + i*size, size);
i = parent(i);//逐个检查父节点
}
}
void* deQueen(priorityQueen *q, int size, int(*compare)(void*, void*))//出队操作
{
assert(q->heapsize >= 1);//断言
void *top = (void*)malloc(size);//暂存最优元素
memcpy(top, (char*)(q->heap), size);//top<-heap[0]
q->heapsize--;
memcpy((char*)q->heap, (char*)q->heap + (q->heapsize)*size, size);//heap[0]<-h[heapsize]
heapify(q->heap, size, 0, q->heapsize, compare);
return top;
}
int empty(priorityQueen *q)
{
return q->heapsize < 1;//检测队列是否为空,若空,返回true
}
void pqeenClear(priorityQueen *q)
{
free(q->heap);
q->heap = NULL;
q->heapsize = q->length = 0;
}
#ifndef _QUEEN_H
#define _QUEEN_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct PriorityQueen
{
int length;//队列容量
int heapsize;//队列中当前所有元素的个数
void *heap;//堆空间
}priorityQueen;//定义一个优先队列结构体类型
priorityQueen heapAlloc(int size, int n);
void enQueen(priorityQueen*q, int size, void *e, int(*compare)(void*, void*));
void* deQueen(priorityQueen *q, int size, int(*compare)(void*, void*));//出队操作
int empty(priorityQueen *q);
void pqeenClear(priorityQueen *q);
#ifdef __cplusplus
{
#endif
#endif /*queen.h*/
#include <stdio.h>
#include <stdlib.h>
#include"compare.h"
#include "sort.h"
#include"merge.h"
#include "partition.h"
#include "heap.h"
#include"queen.h"
int main(int argc, char** argv)
{
int b[] = { 5, 1, 9, 4, 6, 2, 0, 3, 8, 7 }, i;
priorityQueen q = heapAlloc(sizeof(int), 10);
for (i = 0; i < 10; i++)
{
enQueen(&q, sizeof(int), b + i, intLess);
}
while (!empty(&q))
printf("%d ", *(int*)deQueen(&q, sizeof(int), intLess));
printf("\n");
pqeenClear(&q);
system("pause");
return EXIT_SUCCESS;
}
#ifndef _QUEUE_H
#define _QUEUE_H
#include <assert.h>
#include <vector>
using namespace std;
template<typename T,typename Comparator>
class PriQueue
{
private:
vector<T> heap;//队列中元素载体
int heapSize;//队列中元素的个数
public:
PriQueue():heapSize(0){ }//使用构造函数初始化列表进行初始化
void enQueue(T e)
{
heapSize++;
heap.push_back(e);
push_heap(heap.begin(), heap.end(), Comparator());//入队
}
T deQueue()//出队
{
assert(heapSize >= 1);
pop_heap(heap.begin(), heap.end(), Comparator());//将 heap[0]和 heap[heapSize-1] 交换,并将 heap[0...heapSize-2]按比较规则构成一个堆
heapSize--;
T top = heap[heapSize];//保存heap中的最后一个元素到top
heap.erase(heap.end() - 1);//删除heap中的最后一个元素
return top;
}
bool empty()
{
return heapSize < 1;
}
};
#endif /*_QUEUE_H*/
测试代码:
#include "stdafx.h"
#include<string.h>
#include <stdlib.h>
#include <vector>
#include <iterator>
#include <iostream>
#include<algorithm>
#include <functional>//定义运算函数(代替运算符)
#include "sort.h"
#include "merge.h"
#include "partition.h"
#include "heap.h"
#include "queue.h"
using namespace std;
int main(int argc, _TCHAR* argv[])
{
int a[]={4,1,3,2,16,9,10,14,8,7},i;
vector<int> va = vector<int>(a, a + 10);//用数组创建vector对象
PriQueue<int, less<int>> q; //声明一个优先队列对象
for (i = 0; i < 10; i++)
q.enQueue(a[i]);//入队
while (!q.empty())
cout << q.deQueue() << " ";
cout << endl;
system("pause");
return 0;
}
运行结果:16 14 10 9 8 7 4 3 2 1
STL 模版库类priority_queue
#include<iostream>
#include <queue>
using namespace std;
int main(int argc, _TCHAR* argv[])
{
int a[]={4,1,3,2,16,9,10,14,8,7},i;
vector<int> va = vector<int>(a, a + 10);//用数组创建vector对象
priority_queue<int, vector<int>, less<int>> p;
for (i = 0; i < 10; i++)
p.push(a[i]);
while (!p.empty())
{
cout << p.top() << " ";
p.pop();
}
cout << endl;
system("pause");
return 0;
}
标签:优先队列
原文地址:http://blog.csdn.net/u010177286/article/details/45584195