前言:

  看到许多面经说,有时候面试官要你自己当场用模板写出自己的vector容器。于是,我也琢磨着怎么自己动手写一个,可是本人才刚刚学C++模板编程不久,会的不多。不过,我恰好在C++  Primer上看到作者实现了自己的Queue,如果Queue自己实现了,相信Vector也不难了吧?当然这个Queue没有标准库queue的全部功能,只是有它的一部分。我想把书上的Queue敲下来,让自己练练手。

  首先我们来画一下Queue的结构,这样有利于我们理解Queue的构造,使编程思路更加清晰。

  

Queue类的定义:

 //放到Queue.h文件中

 //Queue的完整定义

 //先申明Queue类,因为QueueItem类要用到
#ifndef _QUEUE_HEAD_
#define _QUEUE_HEAD_
template <class type> class Queue; template <class Type>
std::ostream& operator<< (std::ostream&, const Queue<Type>&); template <class Type>
class QueueItem{
//让Queue类成为友元函数,这样Queue里面就可以直接访问QueueItem的私有变量
friend class Queue<Type>;
//将重载后的 << 函数设置为QueueItem的友元函数,以便访问QueueItem的私有变量
friend std::ostream&
operator<< <Type> (std::ostream&, const Queue<Type>&);
//private 成员变量
//复制构造函数
QueueItem(const Type &t):item(t),next() {};
//真正保存数据的成员变量
Type item;
//指向下一个节点的指针
QueueItem *next;
}; //QueueItem类 //下面定义Queue类 template <class Type> class Queue {
friend std::ostream&
operator << <Type> (std::ostream&, const Queue<Type>&);
public:
//默认构造函数
Queue():head(),tail(){}
//根据迭代器范围进行构造的构造函数
template <class It>
Queue(It beg, It end):head(),tail(){copy_elems(beg,end);}
//复制构造函数
Queue(const Queue& Q):head(),tail(){copy_elem(Q);}
//析构函数
~Queue(){destory();}
//赋值函数
Queue& operator = (const Queue&);
//根据迭代器赋值的赋值函数
template <class Iter> void assign(Iter,Iter);
//返队首元素
Type& front();
//根据const重载front函数,以供const对象调用
const Type& front() const;
//向队尾添加元素
void push(const Type&);
//删除队首元素
void pop();
//判断队列是否为空,如果是空返回1,否则返回1
bool empty () const {return head == ;}
private:
//指向队首元素的指针
QueueItem<Type> *head;
//指向队尾元素的指针
QueueItem<Type> *tail;
//删除队列中所有元素的函数
void destory();
//复制队列元素的函数
void copy_elems(const Queue&);
//根据迭代器范围复制队列元素的函数,模板形式
template <class Iter> void copy_elems(Iter,Iter);
};
#include "Queue.cc" //实现
#endif

Queue类的实现:

  //放到Queue.cc文件中

 //实现 << 的重载的实现
template<class Type> std::ostream&
operator << (std::ostream &os,const Queue<Type>&q)
{
os << "<";
QueueItem<Type> *p = q.head; //指向链表的头节点
for(;p;p = p->next)
{
os << p->item << " ";
}
os << ">";
return os;
} //Queue的赋值函数
template <class Type> //模板标志
Queue<Type>& //返回类型
Queue<Type>::operator=//作用域
(const Queue&org) //参数列表
{ //函数体
if(this == &org) //防止自己赋值给自己
return *this;
destory(); //先释放掉自己原来占有的内存资源
copy_elems(org); //复制元素
} //成员函数模板
template<class Type> //第一个模板是类模板
template<class Iter> //第二个模板是成员函数模板
void
Queue<Type>::assign(Iter beg, Iter end)
{
destory();
copy_elems(beg,end);
} //front函数
template<class Type>
Type& Queue<Type>::front()
{
return head->item;
} //const对象调用的const front函数
template<class Type>
const Type& Queue<Type>::front() const
{
return head->item;
} //向队尾添加元素
template <class Type>
void Queue<Type>::push(const Type& val)
{
QueueItem<Type> *p = new QueueItem<Type>(val);
if(p)
{
if(empty())
{
head = tail = p;
}
else
{
tail->next = p;
tail = p;
}
} } //从队首删除元素
template<class Type>
void Queue<Type>::pop()
{
QueueItem<Type> *p = head;
head = head->next;
delete p;
} //清空队列
template<class Type>
void Queue<Type>::destory()
{
while(!empty())
{
pop();
}
} //根据队列复制元素
template<class Type>
void Queue<Type>::copy_elems(const Queue &org)
{
for(QueueItem<Type> *pt = org.head; pt; pt->next)
push(pt->item); //复制
} //根据迭代器范围
template<class Type>
template<class Iter>
void Queue<Type>::copy_elems(Iter beg,Iter end)
{
while(beg != end)
{
push(*beg);
++beg;
}
}

测试Queue功能:

 #include <iostream>
#include <vector>
#include "Queue.h" using namespace std; int main()
{
Queue<int> qi;
int i = ;
//
//
short a[] = {,,,};
vector<int> vi(a,a + );
Queue<int> qi2(a,a+);
qi.push(i);
qi.push();
qi.push();
cout << qi << endl;
cout << qi2 << endl;
qi2.assign(vi.begin(),vi.end());
cout << qi2 << endl;
qi.pop();
cout << qi << endl;
//cout << qi.front() << endl;
//cout << "No Error!" << endl;
return ;
}

  

自己动手实现Queue的更多相关文章

  1. Queues 队列

    1. Definiation What is a queue? A queue is a list. With a queue, inseration is done at one end (know ...

  2. ZOJ 2724 Windows Message Queue (优先级队列,水题,自己动手写了个最小堆)

    #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm& ...

  3. [数据结构]——链表(list)、队列(queue)和栈(stack)

    在前面几篇博文中曾经提到链表(list).队列(queue)和(stack),为了更加系统化,这里统一介绍着三种数据结构及相应实现. 1)链表 首先回想一下基本的数据类型,当需要存储多个相同类型的数据 ...

  4. 给jdk写注释系列之jdk1.6容器(11)-Queue之ArrayDeque源码解析

    前面讲了Stack是一种先进后出的数据结构:栈,那么对应的Queue是一种先进先出(First In First Out)的数据结构:队列.      对比一下Stack,Queue是一种先进先出的容 ...

  5. js 异步流程控制之 avQ(avril.queue)

    废话前言 写了多年的js,遇到过最蛋疼的事情莫过于callback hell, 相信大家也感同身受. 业界许多大大也为此提出了很多不错的解决方案,我所了解的主要有: 朴灵 event proxy, 简 ...

  6. 自己动手写把”锁”---LockSupport介绍

    本篇是<自己动手写把"锁">系列技术铺垫的最后一个知识点.本篇主要讲解LockSupport工具类,它用来实现线程的挂起和唤醒. LockSupport是Java6引入 ...

  7. 自己动手实现java数据结构(四)双端队列

    1.双端队列介绍 在介绍双端队列之前,我们需要先介绍队列的概念.和栈相对应,在许多算法设计中,需要一种"先进先出(First Input First Output)"的数据结构,因 ...

  8. 自己动手写把”锁”---LockSupport深入浅出

    本篇是<自己动手写把"锁">系列技术铺垫的最后一个知识点.本篇主要讲解LockSupport工具类,它用来实现线程的挂起和唤醒. LockSupport是Java6引入 ...

  9. 自己动手写js分享插件 [支持https] (可以分享QQ空间,微信,新浪微博。。。)

    由于百度分享,jiathis 等分享插件在https下均会报错,就萌生了自己动手写一个分享插件的念头,其实实现起来一点都不难,以下代码都已在https网站运行通过,特附上以下代码:还请各位看官不吝赐教 ...

随机推荐

  1. SpringMVC + Spring 3.2.14 + Hibernate 3.6.10 集成详解

    注:此文档只说明简单的框架集成,各个框架的高级特性未涉及,刚刚接触框架的新人可能需要参考其他资料. PS:本次练习所用jar包都能在此下载到:http://pan.baidu.com/s/1sjmgd ...

  2. iOS--日历事件的获取和添加

    日历添加事件 EKEventStore* eventStore = [[EKEventStore alloc] init];//获取日历类 EKEvent *event = [EKEvent even ...

  3. Java编程陷阱-类成员初始化

    原文地址:http://blog.csdn.net/veryitman/article/details/6450523 如果你忽略Java的细节,恐怕你的代码会充满bug,下面讨论关于类成员初始化问题 ...

  4. "_Default"同时存在于两个dll文件中的解决办法

    编译器错误消息:CS0433: 类型“_Default”同时存在于“c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Fi ...

  5. HTML5 <Audio>标签API整理(一)

    简单实例: <audio id="myAudio"></audio> <script> var myAudio = document.getEl ...

  6. 进程识别号(PID)的理解

    PID(Process Identification)操作系统里指进程识别号,也就是进程标识符.操作系统里每打开一个程序都会创建一个进程ID,即PID. PID(进程控制符)英文全称为Process ...

  7. Zend Server安装后首次运行就出现Internal Server Error的解决

    无论是使用哪个版本的Zend Server来搭建PHP服务器,首次运行都会出现Internal Server Error的错误,对很多新手而言,每当看到这种错误时,那一刻内心绝对都是崩溃的.然而,这个 ...

  8. Spring在代码中获取bean的几种方式(转:http://www.dexcoder.com/selfly/article/326)

    方法一:在初始化时保存ApplicationContext对象 方法二:通过Spring提供的utils类获取ApplicationContext对象 方法三:继承自抽象类ApplicationObj ...

  9. POJ3285 River Hopscotch(最大化最小值之二分查找)

    POJ3285 River Hopscotch 此题是大白P142页(即POJ2456)的一个变形题,典型的最大化最小值问题. C(x)表示要求的最小距离为X时,此时需要删除的石子.二分枚举X,直到找 ...

  10. 使用gSoap规避和修改ONVIF标准类型结构的解析

    ONVIF/gSoap依赖关系及问题 ONVIF是一组服务规范,标准参考 gSoap是一套基于实现SOAP通信接口的工具链 即是,当我们需要访问ONVIF的Web Service或实现对ONVIF部分 ...