【3-2】队列

队列的顺序表示和实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

队列的物理存储可以用顺序存储结构,也可用链式存储结构。
队列的存储方式:顺序队列和链式队列

队列的顺序表示:用一维数组base[MaxSize]

#define MaxSize 100//最大队列长度
typedef struct {
QElemType *base;//初始化的动态分配存储空间
int front;//头指针
int rear;//尾指针 从尾部进 用来插入元素 必须是空的
}SqQueue;

初始:front=rear=0;
j1 j2 j3 入队:base[rear]=x; rear++;
j1 h2 出队:x=base[front]; front++;
空队标志:front=rear;

在这里插入图片描述

存在问题!
设数组大小为MaxSize
rear=MaxSize时,发生溢出
if front=0 再入队:真溢出
if front !=0 再入队:假溢出
在这里插入图片描述

解决办法:

1.将队中元素依次向队头方向移动
缺点:浪费时间。每移动一次,队中元素都要移动
2、将队空间想象成一个循环表,当rear=maxsize时,若向量的开始端空着,又可从头使用空着的空间。当front为maxsize时,也是一样。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

引入循环队列
base[0]接在base[maxsize-1]之后,if rear+1==maxsize,则令rear=0;
实现方法:利用模(mod,c语言中%)计算
插入元素:Q.base[Q.rear]=x; Q.rear=(Q.rear+1)%maxsize;
删除元素:x=Q.base[Q.front]; Q.front=(Q.front+1)%maxsize;
队空:rear=front
队满:rear=front
解决方案:
1、另外设一个标志以区别队空、队满
2、另设一个变量,记录元素个数
3、少用一个元素空间
队空:front=rear;
队满:(rear+1)%maxsize=front;
【循环队列的类型定义】

#define maxqsize 100
typedef struct{
qet *base;//动态分配存储空间
int front;//头指针,若队列不空,指向队列头元素
int rear;//尾指针,若队列不空,指向队列尾元素的下一个位置
}squeue;

【循环队列–初始化】

Status InitQueue(SqQueue &Q){
Q.base=new QElemType[maxsize];//分配数组空间
//Q.base=(QElemType *)malloc(maxsize*sizeof(QElemType));
if(!Q.base) exit(OVERFLOW);//存储失败
Q.front=Q.rear=0;//头指针尾指针置为0,队列空
return OK;
}
//注:本文代码全都是类C代码,不能直接运行

循环队列:求队列的长度

int QueueLength(SqQueue Q){
return ((Q.rear-Q.front+maxsize)%maxsize);
}

循环队列入队:

Status InitQueue(SqQueue &Q,QElemtype e){
if((Q.rear+1)%maxsize==Q.front) return ERROR;//队满
Q.base[Q.rear]=e;//新元素加入队尾
Q.rear=(Q.rear+1)%maxsize;
return OK;
}

循环队列出队:

Status InitQueue(SqQueue &Q,QElemtype e){
if(Q.rear==Q.front) return ERROR;//队空
e=Q.base[front];
Q.front=(Q.front+1)%maxsize;//队头指针+1
return OK;
}

循环队列取队头元素:

SElemType InitQueue(SqQueue Q){
if(Q.rear==Q.front) return ERROR;//队空
return Q.base[Q.front];
}

【链队:队列的链式表示和实现】

用户无法估计所用队列的长度,则宜用链队列

#define maxsize 100
typedef struct Qnode{
QElemType data;
struct Qnode *next;
}QNode,*QueuePtr; 
typedef struct{
QueuePtr front;//头指针
QueuePtr rear;//尾指针
}LinkQueue;

a)空队列
Q.front=Q.rear;
b)入队
c)出队
入队、出队

链队列初始化

Status InitQueue(LinkQueue &Q){
Q.front=Q.rear=(QueuePtr) malloc(sizeof(QNode));
if(!Q.front) exit(OVERFLOW);
Q.front->next=NULL;
return OK;
}

销毁链队列

//从队头开始,依次释放所有结点
Status DestoryQueue(LinkQueue &Q){
while(Q.front){
p=Q.front->next;
free(Q.front);
Q.front=p;
}
return OK;
}

将元素e入队

//入队 只能入在队尾
Status EnQueue(LinkQueue &Q,QElemType e){
p=(QueuePtr) malloc(sizeof(QNode));
if(!p) exit(OVERFLOW);
p->data=e;
p->next=null;
Q.rear->next=p;
Q.rear=p;
return OK;
}

链队列出队

//出队 只能出在队头
Status EnQueue(LinkQueue &Q,QElemType &e){
if(Q.front==Q.rear) return ERROR;//队空
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p) Q.rear=Q.front;//如果是最后一个元素要被删除
delete p;
return OK;
}

【求链队列-队头元素–有头结点】

st head(linkqueue q,qet &e){
if(q.front==q.rear) return error;
e=q.front->next->data;
return ok;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值