队列的表示和操作的实现

定义

只能在表的一端进行插入运算,在表的另一端进行删除运算的线性表

逻辑结构

与同线性表相同,仍为一对一关系

存储结构

顺序队或链队,以循环顺序队列更常见

运算规则

只能在队首和队尾运算,且访问结点时按照先进先出的原则

实现方式

关键是掌握入队和出队的操作,具体实现依照顺序队或链队而不同

队列的常见应用

  • 脱机打印输出:按申请的先后顺序输出
  • 多用户系统中,多个用户排成队,分时地循环使用cpu和主存
  • 实时控制系统中,信号按接收的先后顺序依次处理
  • 网络电文传输,按到达的时间先后顺序运行

队列的抽象数据类型定义

ADT Quene{
    数据对象:D = {ai|ai∈ElemSet,i=1,2,…,n,n>=0)
    数据关系:R = {<ai-1,ai>|ai-1,ai∈D,i=2,…,n)  约定其中a1端为队列头,an端为队列尾
    基本操作:
      InitQueue (&Q)  操作结果:构造空队列Q 
      DestroyQueue (&Q)  条件:队列Q已存在;操作结果:队列Q被销毁
      ClearQueue (&Q)  条件:队列Q已存在;操作结果:将Q清空
      QueueLength (Q)  条件:队列Q已存在;操作结果:返回Q的元素个数,即队长
      GetHead (Q,&e)  条件:Q为非空队列;操作结果:用e返回Q的队头元素
      EnQueue (&Q,e)  条件:队列Q已存在;操作结果:插入元素e为Q的队尾元素
      DeQueue (&Q,&e)  条件:Q为非空队列;操作结果:删除 Q 的队头元素,用 e 返回值
      …还有将队列置空、遍历队列等操作…
} ADT Queue
      

队列的物理存储可以用顺序存储结构,也可以用链式存储结构。相应的,队列的存储方式也分为两种,即顺序队列和链式队列

队列的顺序表示——用一维数组base[MAXQISE]
#define MAXQSIZE 100  //最大队列长度
Typedef struct{
   QElemType *base;  //初始化的动态分配内存空间
   int front;  //头指针
   int rear;  //尾指针
}SqQueue;

解决假上溢方法

将队中元素依次向对头方向移动

缺点:浪费时间,每移动一次,队中元素都要移动

引入循环队列

base[0]接在base[MAXQISE-1]之后,若rear+1==M,则令rear=0

实现方法

利用模(mod,C语言中:%)运算

插入元素:Q.base[Q.rear]=x

                  Q.rear=(Q.rear+1)%MAXQSISE

删除元素:x=Q.base[s.front]

                  Q.front=(Q.front+1)%MAXQSISE

如何判断队空队满
解决方案

另外设一个标志以区别队空、队满

另设一个变量,记录元素个数

少用一个元素空间

队空:front==rear

队满:(rear+1)%MAXQSIXSE==front

队列的初始化
Status InitQueue(SqQueue &Q){
   Q.base = new QElemType[NAXQSEZE]  //分配数组空间
   //Q.base = (QElmType*)
   //malloc(MAXQSISE*sezeof(QElemTy03));
   if(!Q.base) exit(OVERFLOW);   //存储分配失败
   Q.front = Q.rear = 0;   //头指针尾指针置为0,队列为空
   return OK;
}
求队列的长度
int QueueLength(SqQueue Q){
   return((Q.rear-Q.front+MAXQSIZE)%MAXQSIZE);
}
循环队列入队
Status EnQueue(SqQueue &Q,QElemType e){
   if((Q.rear+1)%MAXQSIZE==!.front) return ERROR;   //队满
   Q.base[Q.rear]=e;   //新元素加入队尾
   Q.rear=(Q.rear+1)%MAXQSIZE;   //队尾指针+1
   return OK;
}
循环队列出队
Status DeQueue(SqQueue &Q,QElemType e){
   if(Q.front==Q,rear) return ERROR;   //队空
   e=Q.base[Q.front];   //保存队头元素
   Q.front=(Q.front+1)%MAXQSIZE;   //队头指针+1
   return OK;
}
取队头元素
QElemType GetHead(SqQueue Q){
   if(Q.front!=Q.rear)   //队列不为空
     return Q.base[Q.front];   //返回队头指针元素的值,队头指针不变
}
队列的链式表示和实现

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

链队列的类型定义
#define MAXQSIZE 100  //最大队列长度
typedef struct Qnode{
   QElemType data;
   stuct Qnode *next;
}QNode,*QuenePtr;
typedef struct{
   QuenePtr front;  //队头指针
   QuenePtr rear;  //队尾指针
}LinkQueue;
链队列初始化
Status InitQueue(LinkQueue &Q){
   Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
   if(!Q.front) exit(OVERFLOW);
   q.FRONT->next=NULL;
   return OK;
}
链队列销毁

从头结点开始,依次释放所有结点

Status DestroyQueue(LinkQueue &Q){
   while(Q.front){
     p=Q.front->next;
     free(Q.front);
     Q.front=p;
   }
   return OK;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值