"《算法导论》之‘队列’":队列的三种实现(静态数组、动态数组及指针)
本文有关栈的介绍部分参考自网站数据结构。
1. 队列
1.1 队列的定义
队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表。
(1)允许删除的一端称为队头(Front)。
(2)允许插入的一端称为队尾(Rear)。
(3)当队列中没有元素时称为空队列。
(4)队列亦称作先进先出(First In First Out)的线性表,简称为FIFO表。
队列的修改是依先进先出的原则进行的。新来的成员总是加入队尾(即不允许"加塞"),每次离开的成员总是队列头上的(不允许中途离队),即当前"最老的"成员离队。
【例】在队列中依次加入元素a1,a2,…,an之后,a1是队头元素,an是队尾元素。退出队列的次序只能是a1,a2,…,an。
1.2 队列的运算
(1)initQueue(Q)
置空队。构造一个空队列Q。
(2)isEmpty(Q)
判队空。若队列Q为空,则返回真值,否则返回假值。
(3) isFull(Q)
判队满。若队列Q为满,则返回真值,否则返回假值。
注意:
此操作只适用于队列的顺序存储结构。
(4) enQueue(Q,x)
若队列Q非满,则将元素x插入Q的队尾。此操作简称入队。
(5) deQueue(Q)
若队列Q非空,则删去Q的队头元素,并返回该元素。此操作简称出队。
(6) front(Q)
若队列Q非空,则返回队头元素,但不改变队列Q的状态。
2. 实现
在实现的时候,队列的基本函数都有(isEmpty、enQueue、deQueue、front)。因为我是用面向对象的方法来设计队列,所以队列的初始化、拷贝构造、赋值运算符重载等也都具备。另外,我采取了C++中的模板类来设计队列,使得队列设计能适应更多的场合。
队列的实现跟栈的实现没什么大的区别,只需代码细小的修改就OK了。所以,在这里,我只给出基于静态数组的队列的设计。
2.1 基于静态数组
基于静态数组的队列的最大特点就是队列的大小是固定的,用户在初始化之后就无法改变。在编译期,编译器就已经给这个队列分配好内存,在“内存的栈”上分配。
这是我所设计的队列模板类:
template<class T, int defCapacity = >
class Queue
{
public:
Queue();
virtual ~Queue();
bool isEmpty();
bool enQueue(T val); // 通过在队尾添加一个值来改变队列。
T front(); // 访问队首的值,保持队列不变。
bool deQueue(); // 通过删除队首的值来改变一个队列。
int getSizeOfQueue(); private:
T queue[defCapacity];
int sizeOfQueue; };
具体实现代码为:
#include <iostream>
#include <cassert>
using namespace std; // const int CAPACITY = 1024; template<class T, int defCapacity = >
class Queue
{
public:
Queue();
virtual ~Queue();
bool isEmpty();
bool enQueue(T val); // 通过在队尾添加一个值来改变队列。
T front(); // 访问队首的值,保持队列不变。
bool deQueue(); // 通过删除队首的值来改变一个队列。
int getSizeOfQueue(); private:
T queue[defCapacity];
int sizeOfQueue; }; template<class T, int defCapacity>
Queue<T, defCapacity>::Queue()
{
sizeOfQueue = ;
} template<class T, int defCapacity>
Queue<T, defCapacity>::~Queue()
{ } template<class T, int defCapacity>
bool Queue<T, defCapacity>::isEmpty()
{
return sizeOfQueue == ;
} template<class T, int defCapacity>
bool Queue<T, defCapacity>::enQueue(T val)
{
// assert(sizeOfQueue < defCapacity);
bool isSuccess = true;
if (sizeOfQueue == defCapacity)
{
cerr << "There is no space for new elements." << endl;
isSuccess = false;
}
else
{
queue[sizeOfQueue] = val;
sizeOfQueue++;
}
return isSuccess;
} template<class T, int defCapacity>
T Queue<T, defCapacity>::front()
{
//assert(sizeOfQueue > 0);
if (sizeOfQueue == )
{
cerr << "There is no elements in the queue." << endl;
}
return queue[];
} template<class T, int defCapacity>
bool Queue<T, defCapacity>::deQueue()
{
// assert(sizeOfQueue > 0);
bool isSuccess = true;
if (sizeOfQueue == )
{
cerr << "There is no element in Queue." << endl;
isSuccess = false;
}
else
{
for (int i = ; i < sizeOfQueue - ; i++)
{
queue[i] = queue[i + ];
}
sizeOfQueue--;
}
return isSuccess;
} template<class T, int defCapacity>
int Queue<T, defCapacity>::getSizeOfQueue()
{
return sizeOfQueue;
}
queue.hpp
Boost单元测试代码为:
#define BOOST_TEST_MODULE Stack_Test_Module #include "stdafx.h"
#include "../Queue/queue.hpp" const int MAXSIZE = ;
struct Stack_Fixture
{
public:
Stack_Fixture()
{
testQueue = new Queue<int, MAXSIZE>();
} ~Stack_Fixture()
{
delete testQueue;
} Queue<int, MAXSIZE> * testQueue;
}; BOOST_FIXTURE_TEST_SUITE(Stack_Test_Fixture, Stack_Fixture) BOOST_AUTO_TEST_CASE(Queue_Test)
{
// isEmpty ------------------------------------
BOOST_REQUIRE(testQueue->isEmpty() == true); // isEmpty ------------------------------------
BOOST_REQUIRE(testQueue->getSizeOfQueue() == ); // enQueue & front ---------------------------------
BOOST_REQUIRE(testQueue->enQueue() == true);
BOOST_REQUIRE(testQueue->front() == );
BOOST_REQUIRE(testQueue->getSizeOfQueue() == ); BOOST_REQUIRE(testQueue->enQueue() == true);
BOOST_REQUIRE(testQueue->front() == );
BOOST_REQUIRE(testQueue->getSizeOfQueue() == ); BOOST_REQUIRE(testQueue->enQueue() == true);
BOOST_REQUIRE(testQueue->front() == );
BOOST_REQUIRE(testQueue->getSizeOfQueue() == ); BOOST_REQUIRE(testQueue->enQueue() == false);
BOOST_REQUIRE(testQueue->front() == );
BOOST_REQUIRE(testQueue->getSizeOfQueue() == ); // deQueue & front ----------------------------------
BOOST_REQUIRE(testQueue->deQueue() == true);
BOOST_REQUIRE(testQueue->front() == );
BOOST_REQUIRE(testQueue->getSizeOfQueue() == ); BOOST_REQUIRE(testQueue->deQueue() == true);
BOOST_REQUIRE(testQueue->front() == );
BOOST_REQUIRE(testQueue->getSizeOfQueue() == ); BOOST_REQUIRE(testQueue->deQueue() == true);
BOOST_REQUIRE(testQueue->getSizeOfQueue() == ); BOOST_REQUIRE(testQueue->deQueue() == false); } BOOST_AUTO_TEST_SUITE_END()
BoostUnitTest.cpp
2.2 基于动态数组
请参考栈的三种实现(静态数组、动态数组及指针)2.2。
2.3 基于指针
请参考栈的三种实现(静态数组、动态数组及指针)2.3。
本篇博文的代码均托管到Taocode : http://code.taobao.org/p/datastructureandalgorithm/src/.
"《算法导论》之‘队列’":队列的三种实现(静态数组、动态数组及指针)的更多相关文章
- 通过GCD、NSOperationQueue队列、NSThread三种方法来创建多线程
#import "ViewController.h" @interface ViewController () @property (weak, nonatomic) IBOutl ...
- Java的三种代理模式(Spring动态代理对象)
Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩 ...
- 数组的三种方式总结 多维数组的遍历 Arrays类的常用方法总结
一.数组的三种声明方式总结 public class WhatEver { public static void main(String[] args) { //第一种 例: String[] tes ...
- Spring Boot 之 RabbitMQ 消息队列中间件的三种模式
开门见山(文末附有消息队列的几个基本概念) 1.直接模式( Direct)模式 直白的说就是一对一,生产者对应唯一的消费者(当然同一个消费者可以开启多个服务). 虽然使用了自带的交换器(Exchang ...
- 基于visual Studio2013解决算法导论之023队列实现(基于数组)
题目 基于数组的队列 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <time.h> #i ...
- 基于visual Studio2013解决算法导论之022队列实现(基于链表)
题目 基于链表的队列实现 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <time.h> ...
- 基于C#程序设计语言的三种组合算法
目录 基于C#程序设计语言的三种组合算法 1. 总体思路 1.1 前言 1.2 算法思路 1.3 算法需要注意的点 2. 三种组合算法 2.1 普通组合算法 2.2 与自身进行组合的组合算法 2.3 ...
- OpenCV3三种超像素分割算法源码以及效果
OpenCV3中超像素分割算法SEEDS,SLIC, LSC算法在Contrib包里,需要使用Cmake编译使用.为了方便起见,我将三种算法的源码文件从contrib包里拎了出来,可以直接使用,顺便比 ...
- K-means聚类算法的三种改进(K-means++,ISODATA,Kernel K-means)介绍与对比
一.概述 在本篇文章中将对四种聚类算法(K-means,K-means++,ISODATA和Kernel K-means)进行详细介绍,并利用数据集来真实地反映这四种算法之间的区别. 首先需要明确 ...
随机推荐
- 28自定义View 模仿联系人字母侧栏
自定义View LetterView.java package com.qf.sxy.customview02; import android.content.Context; import andr ...
- Linux Debugging (九) 一次生产环境下的“内存泄露”
一个偶然的机会,发现一个进程使用了超过14G的内存.这个进程是一个RPC server,只是作为中转,绝对不应该使用这么多内存的.即使并发量太多,存在内存中的数据太多,那么在并发减少的情况下,这个内存 ...
- mysql-workbench工具update(更新)失败的解决办法
是因为安全模式的保护,所以我们需要设置一下: 如下:windows下是edit–>preferences–>SQL Editor 把右边的最后一行,"safe update&qu ...
- 剑指Offer——归并排序思想应用
剑指Offer--归并排序思想应用 前言 在学习排序算法时,初识归并排序,从其代码量上感觉这个排序怎么这么难啊.其实归并排序的思想很简单:将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列 ...
- Java中Excel导入功能实现、excel导入公共方法_POI -
这是一个思路希望能帮助到大家:如果大家有更好的解决方法希望分享出来 公司导入是这样做的 每个到导入的地方 @Override public List<DataImportMessage> ...
- UNIX网络编程——非阻塞accept
当有一个已完成的连接准备好被accept时,select将作为可读描述符返回该连接的监听套接字.因此,如果我们使用select在某个监听套接字上等待一个外来连接,那就没有必要把监听套接字设置为非阻塞, ...
- 04_NoSQL数据库之Redis数据库:set类型和zset类型
sets类型及操作 Set是集合,它是string类型的无序集合.set是通过hash table实现的,添加,删除和查找复杂度都是0(1).对集合我们可以取并集.交集.差集.通过这些操作我们可 ...
- boost::bad_weak_ptr的原因
出现boost::bad_weak_ptr最可能的原因是enable_shared_from_this<>类构造函数中调用shared_from_this(), 因为构造尚未完成,实例还没 ...
- 【Unity技巧】调整画质(贴图)质量
写在前面 当我们在Unity中,使用图片进行2D显示时,会发现显示出来的画面有明显的模糊或者锯齿,但是美术给的原图却十分清晰. 要改善这一状况实际上很简单. 造成这样的原因,是Unity在导入图片(或 ...
- pycharm+django之小试牛刀
准备好好学习一下python,就从django开始吧,顺带了解一下网站的开发.今天在windows上安装了python,django,以及酷炫吊的IDE--pycharm,学习资料主要是<the ...