对于队列的定义,前人之述备矣。

队列的实现方法与栈非常相似。我直接在我实现的那个栈的代码上加了一点东西,全局替换了一些标识符,就实现了这个队列。

我实现的是一个queue<value>容器类,支持push,pop,top,size,empty,clear和copy construction操作。

主要的实现思路是,先写出几个支持基本操作的类_queue_impl,然后再写一个包装类queue,包装基本操作,再实现size,copy struction,top,clear和抛出异常的功能。这样做(pImpl)的好处不言而喻。

我实现的copy structurion其实是用的一个包装了的友元函数_queue_copy(dst, src),因为这样可以直接访问底部成员并进行复制,比使用用户接口,先一个一个pop,再一个一个push,快多了。

代码使用C++11标准。如果有不对的地方,欢迎指出。

在Win7 mingw32 gcc4.7下编译并测试通过。测试内容非常简单,所以可能会有一些没测试出来的问题。

以下是实现

 #pragma once
#include <cstddef>
#include <stdexcept> namespace jt { template <class value>
class queue {
template <class v>
friend void _queue_copy(queue<v>& dst, const queue<v>& src); private:
struct _queue_impl;
_queue_impl *_impl = nullptr;
size_t _siz; void _init_empty() {
_siz = ;
if (_impl) delete _impl;
_impl = new _queue_impl;
} void _destory() { _siz = ; delete _impl; } public:
queue() { _init_empty(); }
queue(const queue<value> &o) { _queue_copy(*this, o); }
~queue() { _destory(); } void clear() { _init_empty(); }
void push(const value &val) { _impl->push(val); ++_siz; }
size_t size() const { return _siz; } value pop() {
if (_siz == )
throw std::out_of_range("jt::queue::pop() - Empty queue");
--_siz; return _impl->pop();
} bool empty() const { return _siz == ; } value front() const {
if (_siz == )
throw std::out_of_range("jt::queue::front() - Empty queue");
return _impl->f->val;
} value back() const {
if (_siz == )
throw std::out_of_range("jt::queue::back() - Empty queue");
return _impl->b->val;
}
}; template <class value>
static void _queue_copy(queue<value> &dst, const queue<value> &src) {
dst._init_empty();
auto **dn = &dst._impl->f; // dest node for (auto *s = src._impl->f; s; s = s->next) {
*dn = new typename queue<value>::_queue_impl::node;
(*dn)->val = s->val;
dst._impl->b = *dn;
dn = &(*dn)->next;
} dst._siz = src._siz;
} template <class value>
struct queue<value>::_queue_impl {
struct node {
value val;
node *next = nullptr;
} *f = nullptr, // front
*b; // back ~_queue_impl() {
while (f) {
auto *tmp = f->next;
delete f;
f = tmp;
}
} void push(const value& val) {
node *t = new node;
t->val = val; if (f) b->next = t;
else f = t; // if empty, set front b = t;
} value pop() {
value v = f->val; node *tmp = f->next;
delete f;
f = tmp; return v;
}
}; }

[C++][数据结构]队列(queue)的实现的更多相关文章

  1. 用go实现常用算法与数据结构——队列(queue)

    queue 简介 队列是一种非常常见的数据结构,日常生活中也能经常看到.一个典型的队列如下图(图片来自 segmentfault): 可以看出队列和我们日常生活中排队是基本一致的.都遵循 FIFO(F ...

  2. 数据结构 -- 队列Queue

    一.队列简介 定义 队列(queue)在计算机科学中,是一种先进先出的线性表. 它只允许在表的前端进行删除操作,而在表的后端进行插入操作.进行插入操作的端称为队尾,进行删除操作的端称为队头.队列中没有 ...

  3. 数据结构—队列(Queue)

    队列的定义--Queue 队列是只允许在表的队尾插入,在表的队头进行删除.队列具有先进先出的特性(FIFO, First In First Out). 队列提供了下面的操作 q.empty() 如果队 ...

  4. 数据结构-队列(Queue)

    #include <stdio.h> #include <stdlib.h> #define LIST_INIT_SIZE 10 #define LISTINCREMENT 1 ...

  5. Python与数据结构[2] -> 队列/Queue[0] -> 数组队列的 Python 实现

    队列 / Queue 数组队列 数组队列是队列基于数组的一种实现,其实现类似于数组栈,是一种FIFO的线性数据结构. Queue: <--| 1 | 2 | 3 | 4 | 5 |<-- ...

  6. java数据结构——队列、循环队列(Queue)

    每天进步一点点,坚持就是成功. 1.队列 /** * 人无完人,如有bug,还请斧正 * 继续学习Java数据结构————队列(列队) * 队列和栈一样,都是使用数组,但是队列多了一个队头,队头访问数 ...

  7. python基本数据结构栈stack和队列queue

    1,栈,后进先出,多用于反转 Python里面实现栈,就是把list包装成一个类,再添加一些方法作为栈的基本操作. 栈的实现: class Stack(object): #初始化栈为空列表 def _ ...

  8. 数据结构:队列queue 函数push() pop size empty front back

    队列queue: push() pop() size() empty() front() back() push()  队列中由于是先进先出,push即在队尾插入一个元素,如:可以输出:Hello W ...

  9. Java中的队列Queue,优先级队列PriorityQueue

    队列Queue 在java5中新增加了java.util.Queue接口,用以支持队列的常见操作.该接口扩展了java.util.Collection接口. Queue使用时要尽量避免Collecti ...

随机推荐

  1. python word

    代码: #coding=utf-8 __author__ = 'zhm' from win32com import client as wc import os import time import ...

  2. Perplexity Vs Cross-entropy

    Evaluating a Language Model: Perplexity We have a serial of \(m\) sentences: \[s_1,s_2,\cdots,s_m\] ...

  3. 100_1小记ressons analysis

    想到一首诗用以自勉: look to the master, follow the master, walk with the master, see through the master, beco ...

  4. Nancy总结(三)Nancy资料介绍

    Nancy 是一个轻量级用于构建基于 HTTP 的 Web 服务,可以基于 .NET 和 Mono 平台构建轻量级基于 HTTP 的Web 服务.它更多的是借鉴了Ruby的一些特性和Ruby的MVC ...

  5. struts2的DevMode模式

    在实际应用开发或者是产品部署的时候,对应着两种模式: 1.开发模式(devMode),此时,DevMode=true 2.产品模式(proMode),此时,DevMode=false 在一些服务器或者 ...

  6. read name 和 read 在 Bash 中的区别

    read 带一个参数和不带参数的区别是什么,我本以为仅仅是被赋值的变量的名字不同而已: $ read name 1 $ echo "$name" 1 $ read 1 $ echo ...

  7. c++ 类静态成员、非静态成员初始化

    1.静态成员初始化(不能在构造函数或初始化列表中初始化) 1.1 所有静态成员都可以在类定义之外初始化(通用),如下所示 class test { public: static int a; }; ; ...

  8. 加速android源码编译

    添加缓存环境变量 : 在 ~/.bashrc 环境变量文件中 添加 export USE_CCACHE=1环境变量, 加速随后的编译过程; 分配缓存磁盘大小 为 ccache 指定磁盘中的一部分大小, ...

  9. 家庭路由器设置以及win10链接无线不显示登录密码 直接提示链接出错问题解决

    家庭路由器设置 网线插入WAN口,用网客户端接在LAN口,就是路由器模式 LAN→WAN设置:电脑→第二个路由器LAN→进入设置界面: 网络参数→WAN口设置→WAN口连接类型→动态IP→保存. 网络 ...

  10. Linq查询表达式

    目录 1. 概述 2. from子句 3. where子句 4. select子句 5. group子句 6. into子句 7. 排序子句 8. let子句 9. join子句 10. 小结 1. ...