自己动手实现Queue
前言:
看到许多面经说,有时候面试官要你自己当场用模板写出自己的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的更多相关文章
- Queues 队列
1. Definiation What is a queue? A queue is a list. With a queue, inseration is done at one end (know ...
- ZOJ 2724 Windows Message Queue (优先级队列,水题,自己动手写了个最小堆)
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm& ...
- [数据结构]——链表(list)、队列(queue)和栈(stack)
在前面几篇博文中曾经提到链表(list).队列(queue)和(stack),为了更加系统化,这里统一介绍着三种数据结构及相应实现. 1)链表 首先回想一下基本的数据类型,当需要存储多个相同类型的数据 ...
- 给jdk写注释系列之jdk1.6容器(11)-Queue之ArrayDeque源码解析
前面讲了Stack是一种先进后出的数据结构:栈,那么对应的Queue是一种先进先出(First In First Out)的数据结构:队列. 对比一下Stack,Queue是一种先进先出的容 ...
- js 异步流程控制之 avQ(avril.queue)
废话前言 写了多年的js,遇到过最蛋疼的事情莫过于callback hell, 相信大家也感同身受. 业界许多大大也为此提出了很多不错的解决方案,我所了解的主要有: 朴灵 event proxy, 简 ...
- 自己动手写把”锁”---LockSupport介绍
本篇是<自己动手写把"锁">系列技术铺垫的最后一个知识点.本篇主要讲解LockSupport工具类,它用来实现线程的挂起和唤醒. LockSupport是Java6引入 ...
- 自己动手实现java数据结构(四)双端队列
1.双端队列介绍 在介绍双端队列之前,我们需要先介绍队列的概念.和栈相对应,在许多算法设计中,需要一种"先进先出(First Input First Output)"的数据结构,因 ...
- 自己动手写把”锁”---LockSupport深入浅出
本篇是<自己动手写把"锁">系列技术铺垫的最后一个知识点.本篇主要讲解LockSupport工具类,它用来实现线程的挂起和唤醒. LockSupport是Java6引入 ...
- 自己动手写js分享插件 [支持https] (可以分享QQ空间,微信,新浪微博。。。)
由于百度分享,jiathis 等分享插件在https下均会报错,就萌生了自己动手写一个分享插件的念头,其实实现起来一点都不难,以下代码都已在https网站运行通过,特附上以下代码:还请各位看官不吝赐教 ...
随机推荐
- display:table- cell属性的练习
display:table- cell属性指让标签元素以表格单元格的形式呈现,类似于td标签.目前IE8+以及其他现代浏览器都是支持此属性的,但是IE6/7只能对你说 sorry了,这一事实也是大大制 ...
- JQ 让光标在文本框最末尾
function setFocus() { //文本末尾获得焦点 var obj = event.srcElement; var txt = obj.createTextRange(); txt.mo ...
- C#中byte[]与string的转换
1. System.Text.UnicodeEncoding converter = new System.Text.UnicodeEncoding(); byte[] i ...
- 几种不同存储形式下的数据挖掘问题[ZZ]
从原理上说,数据挖掘应该可以应用到任何信息存储方式的知识挖掘中,但是挖掘的挑战性和技术会因为源数据的存储类型的不同而不同.特别是,近年来的研究表明数据挖掘所涉及的数据存储类型越来越丰富,除了一些有通用 ...
- X-Plane数据交互
要用X-Plane进行二次开发,免不了需要进行参数的传递,下面我们来看看与X-Plane进行数据交互都有哪些方式. 与FSX和Flightgear基本一样,X-Plane支持插件,自然也支持通过插件进 ...
- 第四篇、Tomcat 集群
1. 前言 该篇中测试的机器发生了变更,在第一篇中设置的Apache DocumentRoot "d:/deployment"修改为了DocumentRoot d:/clust ...
- jQuery慢慢啃之CSS(六)
1.css(name|pro|[,val|fn])//访问匹配元素的样式属性 $("p").css("color");//获取 $("p") ...
- js submit的問題
form 里面有input name="submit"的时候 $('#seachform').submit();不起作用
- 『重构--改善既有代码的设计』读书笔记----Move Method
明确函数所在类的位置是很重要的.这样可以避免你的类与别的类有太多耦合.也会让你的类的内聚性变得更加牢固,让你的整个系统变得更加整洁.简单来说,如果在你的程序中,某个类的函数在使用的过程中,更多的是在和 ...
- 80端口被占用 PID = 4解决办法
请按照下面的步骤来运行命令:1. sc config http stat = demand2. reboot3. run the command(netsh http show servicestat ...