码迷,mamicode.com
首页 > 其他好文 > 详细

基于二叉树的优先队列

时间:2015-05-08 22:09:07      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:优先队列

  1. 简介
    优先队列:指队列中的元素都被指派一个优先级,元素按优先级最大(最小)出队,存储堆的数组的第一个元素就是最大的(或最小的)。所以用堆作为优先队列的元素载体是合适的。
    队列有两个基本操作:1.入队2.出队。
    队列的特点是先进先出。通常都把队列比喻成排队买东西,大家都很守秩序,先排队的人就先买东西。但是优先队列有所不同,它不遵循先进先出的规则,而是根据队列中元素的优先权,优先权最大的先被取出。通常把优先队列比喻成现实生活中的打印。一个打印店里有很多打印机,每台机器的性能不一样,有的打印机打印很快,有的打印机打印速度很慢。当这些打印机陆陆续续打印完自己的任务时进入排队等候状态。如果我这个时候要打印一份文件,我选的不是第一个排队的打印机,而是性能最好,打印最快的打印机。
    重点:优先级队列,是要看优先级的,谁的优先级更高,谁就先得到权限。不分排队的顺序!
    基本操作:
    empty() 如果队列为空返回真
    pop() 删除对顶元素
    push() 加入一个元素
    size() 返回优先队列中拥有的元素个数
    top() 返回优先队列对顶元素
    在默认的优先队列中,优先级高的先出队。在默认的int型中先出队的为较大的数。

  2. 代码实现(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;
}
  1. 代码实现(c++)
    这里通过定义一个模版类PriQueue来实现优先队列操作
#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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!