自己动手实现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网站运行通过,特附上以下代码:还请各位看官不吝赐教 ...
随机推荐
- idea使用笔记
常用快捷键 ctrl+shift+f12 编辑器全屏 win8下输入法不跟随 使用微软输入法即可 默认设置 之前创建maven工程 每次都要选择自己的版本,原来有个默认全局设置 创建maven模板工程 ...
- 关于this 的一个问题
var name = "the window"; var object = { name:"my object"; getName:function(){ re ...
- mysql 远程访问 配置
sudo vi /etc/mysql/my.cnf 找到bind-address = 127.0.0.1 注释掉这行:#bind-address = 127.0.0.1 或者改为: bind-addr ...
- NSArray 跟 NSMutableArray 使用 区别
NSArray 可变数组 一.NSArray是静态数组,创建后数组内容及长度不能再修改. 实例: //用arrayWithObjects初始化一个不可变的数组对象. //初始化的值之间使用逗号分开,以 ...
- Chess---->简单命令框象棋(人VS人)
简单粗暴,直接先上代码: ChessBoard.h: 1 #ifndef CHESBOARD_H 2 #include<iostream> 3 #include<string& ...
- 你好,C++(2)1.3 C++世界版图1.4 如何学好C++
1.3 C++世界版图 C++语言的发展过程,不仅是一个特性不断增加.内容不断丰富的过程,更是一个在应用领域中不断攻城略地的过程.在其30余年的发展过程中,C++在多个应用领域都得到了广泛的应用和发 ...
- 【转载】【挖掘Treap的潜力】
原帖: http://fanhq666.blog.163.com/blog/static/819434262011021105212299/ 你的Treap能支持以下操作吗?1.区间增减 2.区间求最 ...
- Java学习----this和super(在继承中)
public class Base { /*public Base() { System.out.println("Base 类的初始构造方法"); }*/ public Base ...
- input+div 下拉选择框
前台html页面 <html> <head> <meta name="viewport" content="width=device-wid ...
- SQL服务器名称的更改
SQL服务器名称的更改 1.使用select @@ServerName可以看到当前数据库的服务器名称 2.从Sys.SysServers表中可以看到当前的所有服务器名称 3.使用 sp_drops ...