概念
队列是一种只允许在表的一端插入,在另一端删除的操作受限的线性表。像排队一样,入队时排在队尾,到达越早的结点离开的越早。所以队列的特点是先进先出。
对头:允许删除的一端(front)
队尾:允许插入的一端(rear)
当队列中没有元素是称为空队列。
顺序队列
1.使用顺序表来实现队列
2.两个指针分别指向队列的前端和尾端
3.若队列大小MaxSize个,元素下标范围从0到maxsize-1
约定:队头指针front指向队头元素的前一个位置,队尾指针rear指向队尾元素
循环队列
空队列条件:Q.rear=Q.front;
满队列条件:Q.rear=Q.front;
如何区别队空和队满:
1.牺牲一个存储空间,队满条件**(Q.rear+1)%maxsize=Q.front**
2.引入一个标志变量区别空和不空
3.使用计数器
牺牲一个存储空间公式:
1.队满的条件: (rear +1)% MaxSize == front2.队空的条件: front == rear
3.队列中元素个数:(rear - front +MaxSize) % MaxSize
4.入队:rear = (rear + 1) % maxSize
5. 出队:front = (front+1)% maxSize
顺序队列的类型定义
:
template<class T>
class seqQueue
{private:
T*data;//指针指向存放元素的数组
int maxsize;//队列的大小
int front,rear;//队头队尾指针
#define Maxsize 50
typedef struct
{Elemtype data[Maxsize];
int front ,rear;
}SeQueue;
循环队列 初始化
template<class T>
seqQueue<T>::seqQueue(int initesize){
if(inisize<=0) throw babsize();
data=new T[inisize];
maxsize=initsize;
front=rear=0;
}
void INitqueue(SqQueue&Q){
Q.rear=Q.front=0;
}
入队
template<class T>
void seqQueue<T>::enqueue(const T&x){
if((rear+!)%naxsize==front)resize();//若队列满,扩大队列
rear=(rear+1)%maxsize;//移动队尾指针
data[rear]=x;//x入队
}
bool EnQueue(SqQueue&Q,Elemtype&x){
if(Q.rear==Q.front) return false;
Q.data[Q.rear]=x;
Q.rear=(Q.rear+1)%maxsize;
return true;
}
出队
template<class T>
void seqQueue<T>::dequeue(){
if(empty()) throw outOfrange();//若队列空,抛出异常
front=(front+1)%maxsize;//移动队首指针
return data[front];//返回队首元素
}
时间复杂度O(1)
bool DeQueue(SqQueue&Q,Elemtype&x){
if(Q.rear==Q.front) return false;
x=Q.data[Q.front];
Q.front=(Q.front+1)%maxsize;
return true;
}
取队首元素
只需返回值,无需修改。
template <class T>
T seqQueue<T>::getHead()const{
if(empty()) throw outOfrange();
return data[{front+1)%maxsize];
}
链队列
链队列类型定义
template<class T>
class linkQueue{
private:
struct node{
T data;node*next;//数据域,指针域
node(const T&x,node*N=NULL){data=x;next=N;}
node():next(NULL){}
~node(){}
};
node*front,*rear;
......};
typedef struct{//链式队列结点
Elemtype data;
struct LinkNode*next;
}LinkNode;
typedef struct{
linkNode*front,*rear;//队列的队头和队尾指针
}LinkQueue;
入队
template <class T>
void linkQueue<T>::enQueue(const T&x){
if(rear==NULL)//原队列为空
front=rear=new node(x);//入队元素既是队首,又是队尾
else{
rear->next=new node(x);//在队尾入队
rear=rear->next;//修改队尾指针
}
}
时间复杂度O(1)
void EnQueue(LInkQueue&Q,Elemtype x){
LinkNode*s=(LinkNode*)malloc(sizeof(LinkNode));
s->data=x;s->next=NULL;
Q.rear->next=s;
Q.rear=s;
}
出队
template<class T>
T linkQueue<T>::deQueue(){
if(empty()) throw outofrange();//队列空
node*p=front;
T value=front->data;//保存队首元素
front=front->next;//在队首出队
delete p;
//原来只有一个元素,出对后队列为空
if(front==NULL) rear=NULL;//修改队尾指针
return value;
}
bool DeQueue(LinkQueue&Q,ElemType&x){
if(Q.front==Q.rear) return false;
LinkNode*p=Q.front->next;
x=p->data;
Q.front->next=p->next;
if(Q.rear==p)
Q.front=Q.rear;//原队列只有一个结点,删除后变空
delete p;
return true;
}
取队首元素
template<class T>
T linkQueue<T>::getHead()const{
if(empty()) throw outofrange();//队列空
return front->data;//返回队首元素
}
求队列长度
template<class T>
int linQueue<T>::size()const{
node*p=front;
int count=0;
while(p){
count++;
p=p->next;
}//p为空时退出循环
return count;
}
时间复杂长度O(n)