当前位置: 首页 > news >正文

队列queue

一、定义

队列(queue)是一个线性表,其插入和删除操作分别在表的不同端进行

添加新元素的那一端被称为队尾(queueBack) 或qBack

删除元素的那一端被成为队首(queueFront)  或qFront

队列是一个先进先出(first-in-first-out, FIFO)的线性表

抽象类(queue.h):

#ifndef queue_
#define queue_using namespace std;template<class T>
class queue 
{public:virtual ~queue() {}virtual bool empty() const = 0;// return true iff queue is emptyvirtual int size() const = 0;// return number of elements in queuevirtual T& front() = 0;// return reference to the front elementvirtual T& back() = 0;// return reference to the back elementvirtual void pop() = 0;// remove the front elementvirtual void push(const T& theElement) = 0;// add theElement at the back of the queue
};
#endif

二、队列 数组描述(循环队列)

 int queueFront;删除
int queueBack;添加
int arrayLength;数组长度
T *queue;数组指针

描述队列的数组被视为一个“环” ,qBack抵达数组最后可使用数组开始的空间。

使用 i % n 表示队列的第i个元素到数组对应位置的映射:

第0,1,2,3个元素映射到第0,1,2,3个位置,第4个元素映射到第0个位置。

qFront修改为指向队头前一个位 置(总为空)队列不能插满:最多n-1个元素

此时:

队列不能插满:最多n-1个元素

qFront修改为指向队头前一个位置(总为空)

队列为空:qFront == qBack 队列为满:(qBack + 1)%n == qFront

arrayQueue:

template <typename T>class arrayQueue: public queue<T>{private:int queueFront;int queueBack;int arrayLength;T *queue;public:arrayQueue(intinitialCapacity = 10);~arrayQueue () { delete [] queue; }bool empty()const{ return queueFront== queueBack; }//队列为空:qFront == qBackint size()const{ return (arrayLength + queueBack- queueFront) % arrayLength;}T& front()const;T& back()const;voidpop();voidpush(constT& theElement);};

(arrayLength + queueBack- queueFront) % arrayLength是为了使得出结果为正数。

构造函数:

template<class T>
arrayQueue<T>::arrayQueue(int initialCapacity)
{if (initialCapacity < 1){ throwillegalParameterException("");}arrayLength = initialCapacity;queue = new T[arrayLength];theFront =theBack= 0;
}

读队头/尾:

template<classT>T&arrayQueue<T>::front() const{if(queueFront == queueBack) throwqueueEmpty();return queue[(queueFront + 1) % arrayLength];}template<classT>T&arrayQueue<T>::back()const{if(queueFront == queueBack) throwqueueEmpty();return queue[queueBack];}

先判断是否为空,非空时返回头/尾。头时需要计算+1,需要取模保证指针指向队头元素,而尾未进行运算不需要取模。

push与pop:

pop:
template<classT>void arrayQueue <T>::pop(){if (queueFront == queueBack) throwqueueEmpty();queueFront=(queueFront + 1) % arrayLength;queue[queueFront].~T();}

先判断是否为空,非空时queueFront+1取模,然后调用该元素类型析构函数。

push:
template<classT>void arrayQueue<T>::push(const T& theElement){if ((queueBack + 1)% arrayLength == queueFront){…}//扩展队列queueBack= (queueBack+ 1)% arrayLength;queue[queueBack] = theElement;}
数组扩展:
if ((theBack + 1) % arrayLength == theFront)
{//扩容二倍T* newQueue = new T[2 * arrayLength];  //容量为二倍的数组int start = (theFront + 1) % arrayLength;//theFront为第一个元素前一个位置,start为队列第一个元素的位置if (start < 2)//start<2时无回绕copy(queue + start, queue + start + arrayLength - 1, newQueue);//从start位置开始,复制arrayLength - 1个元素(原队列的全部元素)到新数组的起始位置else{  //有回绕copy(queue + start, queue + arrayLength, newQueue);//先复制start到原数组末尾的元素到新数组开头copy(queue, queue + theBack + 1, newQueue + arrayLength - start);//再复制原数组开头到queueBack的元素,拼接在前一部分之后(偏移量为arrayLength - start,//即第一部分的元素个数)}theFront = 2 * arrayLength - 1;theBack = arrayLength - 2;   // queue size arrayLength - 1arrayLength *= 2;queue = newQueue;}

队列 链表描述

两个指针指头和尾,一个queueSize表示大小

队头就是链表头,队尾就是链表尾

 template<typenameT>class LinkedQueue:publicqueue<T>{private:chainNode<T>* queueFront;chainNode<T>* queueBack;int queueSize;public:LinkedQueue(intinitialCapacity = 10);~LinkedQueue();boolempty()const {returnqueueSize== 0; }int size()const { return queueSize; }T& front();T& back();voidpush(constT& theElement);voidpop();};

front和back:

template<classT>T& LinkedQueue<T>::front(){if (queueSize == 0)throw queueEmpty();return queueFront->element;}template<classT>T& LinkedQueue<T>::back(){if (queueSize == 0)throw queueEmpty();return queueBack->element;}

push和pop:

template<classT>void LinkedQueue<T>::push(constT&theElement){chainNode<T>* newNode =new chainNode<T>(theElement, nullptr);if(queueSize!=0)queueBack->next = newNode;elsequeueFront=newNode;queueBack= newNode;queueSize++;}template<classT>void LinkedQueue<T>::pop(){if(queueFront == NULL)throw queueEmpty();chainNode<T>* nextNode= queueFront->next;delete queueFront;queueFront=nextNode;queueSize--;}

三、应用:列车重排

int NowOut =1; // NowOut:下一次要输出的车厢号
for(int i=1; i<=n; i++){ //从前至后依次检查的所有车厢
1.车厢p[i]从入轨上移出
2.if(p[i] == NowOut) // NowOut:下一次要输出的车厢号
2.1使用缓冲铁轨Hk把p[i]放到出轨上去; NowOut++;2.2 while (minH (当前缓冲铁轨中编号最小的车厢) == NowOut) {
把minH放到出轨上去;
更新minH,minQ(minH所在的缓冲铁轨);NowOut++;}else按照分配规则将车厢p[i]送入某个缓冲铁轨
}
// railroad car rearrangement using queues#include <iostream>
#include "arrayQueue.h"using namespace std;// global variables
arrayQueue<int>* track;      // array of holding tracks
int numberOfCars;
int numberOfTracks;
int smallestCar;        // smallest car in any holding track
int itsTrack;           // holding track with car smallestCarvoid outputFromHoldingTrack()
{// output the smallest car from the holding tracks// pop smallestCar from itsTracktrack[itsTrack].pop();cout << "Move car " << smallestCar << " from holding track "<< itsTrack << " to output track" << endl;// find new smallestCar and itsTrack by checking all queue frontssmallestCar = numberOfCars + 2;for (int i = 1; i <= numberOfTracks; i++)if (!track[i].empty() && track[i].front() < smallestCar){smallestCar = track[i].front();itsTrack = i;}
}bool putInHoldingTrack(int c)
{// Put car c into a holding track.// Return false iff there is no feasible holding track for this car.// find best holding track for car c// initializeint bestTrack = 0,  // best track so farbestLast =  0;  // last car in bestTrack// scan tracksfor (int i = 1; i <= numberOfTracks; i++)if (!track[i].empty()){// track i not emptyint lastCar = track[i].back();if (c > lastCar && lastCar > bestLast){// track i has bigger car at its rearbestLast = lastCar;bestTrack = i;}}else // track i emptyif (bestTrack == 0)bestTrack = i;if (bestTrack == 0)return false; // no feasible track// add c to bestTracktrack[bestTrack].push(c);cout << "Move car " << c << " from input track "<< "to holding track " << bestTrack << endl;// update smallestCar and itsTrack if neededif (c < smallestCar){   smallestCar = c;itsTrack = bestTrack;}return true;
}bool railroad(int* inputOrder,int theNumberOfCars, int theNumberOfTracks)
{// Rearrange railroad cars beginning with the initial order.// inputOrder[1:theNumberOfCars]// Return true if successful, false if impossible.numberOfCars = theNumberOfCars;// keep last track open for outputnumberOfTracks = theNumberOfTracks - 1;// create queues track[1:numberOfTracks] for use as holding trackstrack = new arrayQueue<int> [numberOfTracks + 1];int nextCarToOutput = 1;smallestCar = numberOfCars + 1;  // no car in holding tracks// rearrange carsfor (int i = 1; i <= numberOfCars; i++)if (inputOrder[i] == nextCarToOutput){// send car inputOrder[i] straight outcout << "Move car " << inputOrder[i] << " from input "<< "track to output track" << endl;nextCarToOutput++;// output from holding trackswhile (smallestCar == nextCarToOutput){outputFromHoldingTrack();nextCarToOutput++;}}else// put car inputOrder[i] in a holding trackif (!putInHoldingTrack(inputOrder[i]))return false;return true;
}// test program
int main()
{//int p[] = {0, 5, 8, 1, 7, 4, 2, 9, 6, 3};//cout << "Input permutation is 581742963" << endl;int p[] = {0, 3, 6, 9, 2, 4, 7, 1, 8, 5};cout << "Input permutation is 369247185" << endl;railroad(p, 9, 3);return 0;
}

http://www.dtcms.com/a/435725.html

相关文章:

  • 网站平台规划最便宜的网站叫什么名字
  • 【Java】从入门到放弃-05:高级语法
  • 全国十大网站建设公司wordpress mp6
  • 责任链与规则树设计实战解析(自用)
  • 网站建设太金手指六六二九代理产品网
  • 栾城做网站云南信息发布平台
  • DrissionPage爬取汽车之家:(车名 + 颜色 + 车辆型号/续航里程)
  • 360做企业网站多少钱淘宝客网站怎么做的
  • 网站制作课程介绍清远网站制作公司
  • 宁志网站两学一做匀贵网站建设
  • 树莓派点亮LED灯
  • 如何解决 pip install -r requirements.txt 安装报错 递归包含:文件通过 -r 引用了自身 问题
  • 【实证分析】A股上市公司权益资本成本数据-基于MPEG模型(2001-2024年)
  • 制作公司工作网站网站数据库是干什么的
  • 亚马逊网站建设目的wordpress证优客
  • 科技信息差(10.2)
  • 设计网站的目的重庆九龙坡营销型网站建设公司推荐
  • 建设ftp网站的安全性网站建设模板可用吗
  • 优秀网站作品做网站cpa
  • 网站 被刷流量东营网约车最新消息
  • 电路中的 ”CT“
  • 自建网站和第三方平台自己做众筹网站
  • 网站做流量是怎么回事邢台网站建设有哪些
  • 文本引导的图像融合方法
  • 免费空间访客100个网站桓台网站建设公司
  • 网站防盗链怎么做制作html网页的详细步骤
  • 网站建设微享互动桂林市区面积
  • 怎么看网站是否备案成功建筑木工招聘平台
  • 合肥网站制作哪家有名网站建设的步骤教程视频
  • 天博网站建设如何做网页宣传