使用数组和模板实现的队列

队列是一种先进先出的数据结构,可以作为一种缓存机制,在项目中常被用到。队列的实现可以基于链表和数组。链表的优点在于:取头尾元素以及向链表中插入元素的时间复杂度为O(1),且充分利用已分配的存储空间,绝不浪费。而数组由于是连续存储,所以存取元素的速度快。因此在STL中vector的应用要远多于list,以达到以最小的代价实现数据的连续存储。
STL queue是常用的队列,可以满足实际中的各种应用。STL queue实际上是一种适配器(adapter),其实现是基于STL的容器deque。deque是一种双端队列,是由一段段定量连续的空间组成,为了这种实现,deque使用了相对复杂的迭代器架构设计;因此在存取速度上不及数组。本文基于存取速度,用数组和模板实现循环队列,并和STL queue进行对比。
队列的实现代码如下:

#ifndef _SIMPLEQUEUE_H_
#define _SIMPLEQUEUE_H_

template <class Type>
class SimpleQueue
{
public:
    //构造函数
    SimpleQueue( );
    //析构函数
    ~SimpleQueue();
    //入队
    bool EnQueue(const Type &);
    //出队
    bool DeQueue(Type &);
    //判断队列是否满
    bool IsFull()const;
    //判断队列是否为空
    bool IsEmpty()const;
private:
    enum { nQueueSize = 1024 } ;
    int nCurSize ; // 队列当前容量
    int nCurFront ; // 当前队首的位置
    int nCurRear ; // 当前队尾的位置
    Type m_vQueue[nQueueSize];
};

template <class Type>
SimpleQueue<Type>::SimpleQueue( )
{
    nCurSize = 0 ; 
    nCurFront = 0 ;
    nCurRear = 0 ;
}

template <class Type>
SimpleQueue<Type>::~SimpleQueue( )
{
}

template <class Type>
bool SimpleQueue<Type>::EnQueue(const Type &element)
{
    if( IsFull() )
    {
        return false;
    }
    m_vQueue[nCurRear++ % nQueueSize] = element ;
    ++nCurSize ;
    return true;
}

template <class Type>
bool SimpleQueue<Type>::DeQueue(Type &element)
{
    if( IsEmpty() )
    {
        return false;
    }
    element = m_vQueue[nCurFront++ % nQueueSize];
    --nCurSize ;
    return true;
}
template <class Type>
bool SimpleQueue<Type>::IsFull( )const
{
    return nCurSize >= nQueueSize ;
}

template <class Type>
bool SimpleQueue<Type>::IsEmpty( )const
{
    return nCurSize <= 0 ;
}

#endif

下面对SimpleQueue和STL queue的存取速度进行对比,向队列中插入1024个元素,然后进行出队,统计10000次实验所需的总时间。实验在32位CentOS release 5.5 (Final)CPU主频2094.750HZ的虚拟机上进行,时间结果为微秒。

#include "SimpleQueue.h"
#include <iostream>
#include <queue>
#include <cstdlib>
#include <sys/time.h>

using namespace std;

const int times = 10000 ;
const int nQueueSize = 1024 ;
int main()
{
    //simplequeue
    SimpleQueue<int> qi;
    struct timeval tBegin;
    struct timeval tEnd ;
    int num ;
    long long elapse ;
    gettimeofday(&tBegin ,NULL);
    srand(time(NULL));
    for(int t = 0 ; t < times ;++t)
    {
        for(int i = 0 ; i < nQueueSize; ++i )
        {
            qi.EnQueue( (rand() % nQueueSize) );
        }
        while(!qi.IsEmpty())
        {
            qi.DeQueue(num);
        }
    }
    gettimeofday(&tEnd ,NULL);
    elapse = (tEnd.tv_sec - tBegin.tv_sec)*1000000 + (tEnd.tv_usec - tBegin.tv_usec);
    cout<<"simpleQueue:"<<elapse<<"us"<<endl;
    //stl queue
    queue<int> stdqi;
    gettimeofday(&tBegin ,NULL);
    for(int t = 0 ; t < times ;++t)
    {
        for(int i = 0 ; i < nQueueSize; ++i )
        {
            stdqi.push( (rand() % nQueueSize) );
        }
        while(!stdqi.empty())
        {
            stdqi.pop();
        }
    }
    gettimeofday(&tEnd ,NULL);
    elapse = (tEnd.tv_sec - tBegin.tv_sec)*1000000 + (tEnd.tv_usec - tBegin.tv_usec);
    cout<<"STLQueue:"<<elapse<<"us"<<endl;
    return 0;
}

编译:g++ -g main.cpp -o run
运行结果为:
[root@localhost queue]# ./run
simpleQueue:686664us
STLQueue:958892us
可见在存取元素的速度上,simplequeue还是优于stlqueue,因此在数据量巨大,而又需要频繁存取队列时,如果对程序的运行时间有要求,那么STLqueue就存在可被替换的理由。当然,上述的比较并不能全面说明问题,STLqueue具有丰富的接口,鲁棒的实现,还是很多应用中的首选。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值