博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构(九)——队列
阅读量:6351 次
发布时间:2019-06-22

本文共 5232 字,大约阅读时间需要 17 分钟。

数据结构(九)——队列

一、队列简介

队列是一种特殊的线性表,仅能在两端进行操作,队头可以进行区数据操作,队尾进行插入数据操作。

队列的特性是先进先出。
数据结构(九)——队列
队列的操作包括创建队列、销毁队列、入队、出队、清空队列、获取队头元素、获取队列的长度。

二、队列的实现

1、队列的抽象类

template 
class Queue:public Object { public: virtual void add(const T& value) = 0;//进队列 virtual void remove() = 0;//出队列 virtual T front()const = 0;//获取队头元素 virtual void clear() = 0;//清空队列 virtual int length()const = 0;//队列长度 };

2、队列的顺序存储结构实现

队列可以使用顺序存储结构的内存空间实现,其内存空间分布如下:

数据结构(九)——队列
根据存储空间的分配方式可以分为使用原生数组实现的静态队列和使用动态分配的堆空间实现的动态队列。
静态队列的实现要点如下:
A、类模板实现
B、使用原生数组作为队列的存储空间
C、使用模板参数决定队列的容量大小
静态队列的实现如下:

template 
class StaticQueue:public Queue
{ protected: T m_space[N];//队列存储空间,N为模板参数 int m_front;//队头标识 int m_rear;//队尾标识 int m_length;//队列长度 public: StaticQueue() { m_front = 0; m_rear = 0; m_length = 0; } int capacity()const { return N; } void add(const T &value)//入队 { if(m_length < N) { m_space[m_rear] = value; m_rear = (m_rear + 1) % N; m_length++; } else { THROW_EXCEPTION(InvalidOperationException, "No enough memory..."); } } void remove()//出队 { if(m_length > 0) { m_front = (m_front + 1) % N; m_length--; } else { THROW_EXCEPTION(InvalidOperationException, "No element..."); } } T front() const//取队头元素 { if(m_length > 0) { return m_space[m_front]; } else { THROW_EXCEPTION(InvalidOperationException, "No element..."); } } void clear()//清空队列 { m_length = 0; m_front = 0; m_rear = 0; } int length() const { return m_length; } bool isEmpty()const { return (m_length == 0) && (m_front == m_rear); } bool isFull()const { return (m_length == N) && (m_front == m_rear); } };

静态队列的缺陷:

当存储的元素类型为类类型时,创建静态队列时会多次调用元素类型的类构造函数,影响效率。

3、队列的链式存储结构实现

队列使用链式存储结构实现的内容空间分布如下:

数据结构(九)——队列
链式队列的实现要点:
A、类模板实现,继承自抽象父类Queue
B、内部使用链式结构实现元素的存储
C、只在链表的头部和尾部进行操作
链式队列的实现:

template 
class LinkedQueue:public Queue
{ protected: LinkedList
m_list; public: LinkedQueue() { } void add(const T& value)//入队 { m_list.insert(value); } void remove()//出队 { if(m_list.length() > 0) m_list.remove(0); else { THROW_EXCEPTION(InvalidOperationException, "No enough memory..."); } } T front()const//获取队头元素 { if(m_list.length() > 0) return m_list.get(0); else { THROW_EXCEPTION(InvalidOperationException, "No elemnet..."); } } void clear()//清空队列 { m_list.clear(); } int length() const { return m_list.length(); } };

三、栈和队列的相互实现

1、栈实现队列

用栈实现队列,用栈的后进先出的特性实现队列的先进先出的特性。

用栈实现队列需要使用两个栈,解决方案如下:
数据结构(九)——队列
新元素入队时,将元素压入stack_in栈,

template 
class StackToQueue:public Queue
{protected: mutable LinkedStack
m_stack_in; mutable LinkedStack
m_stack_out;public: void add(const T& value)//入队 { m_stack_in.push(value); } void remove()//出队 { //出栈为空,则将入栈的所有元素压入出栈并弹出入栈的元素 if(m_stack_out.size() == 0) { while(m_stack_in.size() > 0) { m_stack_out.push(m_stack_in.top()); m_stack_in.pop();//弹出入栈的元素 } } //出栈不为空,将出栈栈顶元素弹出 if(m_stack_out.size() > 0) { m_stack_out.pop(); } else { THROW_EXCEPTION(InvalidOperationException, "No element..."); } } T front() const { if(m_stack_out.size() == 0) { while(m_stack_in.size() > 0) { m_stack_out.push(m_stack_in.top()); m_stack_in.pop(); } } //弹出出栈栈顶元素 if(m_stack_out.size() > 0) { return m_stack_out.top(); } else { THROW_EXCEPTION(InvalidOperationException, "No element..."); } } void clear() { m_stack_in.clear(); m_stack_out.clear(); } int length()const { return m_stack_in.size() + m_stack_out.size(); }};

2、队列实现栈

用队列实现栈,用队列的先进先出的特性实现栈的后进先出的特性。

用队列实现栈需要使用两个队列,解决方案如下:
数据结构(九)——队列

template 
class QueueToStack:public Stack
{protected: LinkedQueue
m_queue1; LinkedQueue
m_queue2; LinkedQueue
* m_pIn;//入队列 LinkedQueue
* m_pOut;//出队列 //将入队列前n-1个元素移动到出队列 void move()const { int n = m_pIn->length() - 1; for(int i = 0; i < n; i++) { m_pOut->add(m_pIn->front()); m_pIn->remove();//从入队列出队 } } //交换 void swap() { LinkedQueue
* temp = NULL; temp = m_pIn; m_pIn = m_pOut; m_pOut = temp; }public: QueueToStack() { m_pIn = &m_queue1; m_pOut = &m_queue2; } //压栈 void push(const T& value) { m_pIn->add(value);//将元素入队列 } void pop()//出栈 { if(m_pIn->length() > 0) { move();//移动前n-1个元素 m_pIn->remove();//将入队列的最后一个元素出队 swap();//交换 } else { THROW_EXCEPTION(InvalidOperationException, "No element..."); } } void clear() { m_queue1.clear(); m_queue2.clear(); } T top() const { if(m_pIn->length() > 0) { move();//移动 return m_pIn->front(); } else { THROW_EXCEPTION(InvalidOperationException, "No element..."); } } int size()const { return m_queue1.length() + m_queue2.length(); }};

转载于:https://blog.51cto.com/9291927/2063401

你可能感兴趣的文章
继 One Step 后,锤子科技 Big Bang 正式开源
查看>>
《数据科学:R语言实现》——2.5 使用Excel文件
查看>>
《淘宝店铺设计装修一册通》一2.5 抠图工具的简单运用
查看>>
《音乐达人秀:Adobe Audition实战200例》——实例4 收音机音乐节目转录到电脑里...
查看>>
《JavaScript应用程序设计》一一3.1 过时的类继承
查看>>
千万PV是什么意思?
查看>>
Amazon 推出 API 网关使用计划
查看>>
互联网流量超出路由器上限 或致全球断网
查看>>
《基于ArcGIS的Python编程秘笈(第2版)》——2.5 限制图层列表
查看>>
GNOME 地图 3.20 加入更多新特性 可用性得到加强
查看>>
《代码整洁之道:程序员的职业素养》导读
查看>>
《计算复杂性:现代方法》——习题
查看>>
Mozilla 释出更新修复中间人攻击漏洞
查看>>
思科表态反对网络中立
查看>>
《HTML5+CSS3网页设计入门必读》——1.5 利用多种Web浏览器执行测试
查看>>
Velocity官方指南-容器
查看>>
国家为何如此重视石墨烯?
查看>>
《Python和Pygame游戏开发指南》——1.14 配套网站上的更多信息
查看>>
Kafka+Flink 实现准实时异常检测系统
查看>>
利用mybatis查询两级树形菜单
查看>>