(史上最完整) 队列 的基本操作和实现 及排队系统实例

目录

一:队列的表示和操作的实现

1.1 队列的示意图

1.2  队列的介绍

1.3:相关概念

1.4 实际生活中的实例

二:队列的抽象数据结构和 操作代码

2.1 抽象的数据结构

 2.2 队列的顺序表示和实现 (分析和思考)

2.2.1 顺序队列的数据结构

2.2.2 顺序队列的入队和出队 图示:

​编辑​编辑

 2.2.3 溢出思考:

2.3循环队列的表示和实现

2.3.1 循环队列的类型定义

2.3.2 循环队列的初始化

2.3.3 循环队列的求队列长度

2.3.4 循环队列入队

2.3.5  循环对列的出队

2.3.6 取队头元素

2.4:链队的表示和实现

关于链队的一些重点

2:链式队列的表示和基本操作

实例练习:行排队叫号系统



一:队列的表示和操作的实现

1.1 队列的示意图

 类似:排队 滴水漏斗

1.2  队列的介绍

  • 队列(Queue)是仅在表尾进行插入操作,在表头进行删除操作的线性表
  • 表尾即an端,称为队尾; 表头即a1端,称为队头。
  • 它是一种先进先出( FIFO )的线性表。

  • 插入元素称为人队;删除元素称为出队。
  • 队列的存储结构为链队或顺序队(常用循环顺序队)

1.3:相关概念

逻辑结构:同线性表 一一对应关系

存储结构:顺序和链队,循环队列最常见

运算规则:只在队首和队尾运算,先进先出FIFO原则

实现方式:入队和出队等重要实现方式

1.4 实际生活中的实例

■脱机打印输出:按申请的先后顺序依次输出。
■多用户系统中,多个用户排成队,分时地循环使用CPU和主存
■按用户的优先级排成多个队,每个优先级一个队列
■实时控制系统中,信号按接收的先后顺序依次处理

二:队列的抽象数据结构和 操作代码

2.1 抽象的数据结构

 2.2 队列的顺序表示和实现 (分析和思考)

2.2.1 顺序队列的数据结构

#define MAXQSIZE 100 //最大队列长度

typedef struct{

        QElemType *base;//初始化的动态分配存储空间

        int front;// 头指针

        int rear; //尾指针

}SqQueue;

2.2.2 顺序队列的入队和出队 图示:

 2.2.3 溢出思考:

数组大小为MAXQSIZE 

 rear = MAXQSIZE    front !=0 再入队,发生假溢出

rear =MAXQSIZE      front = 0 再入队,发生真溢出

 如何解决假上溢? 循环队列

 解决方法:

 继续解决:队满判断方法

 

 

2.3循环队列的表示和实现

2.3.1 循环队列的类型定义

#define MAXQSIZE 100 //最大队列长度

typedef struct{

        QElemType *base;//初始化的动态分配存储空间

        int front;// 头指针

        int rear; //尾指针

}SqQueue;

2.3.2 循环队列的初始化

Status InitQueue(SqQueue &Q){

        Q.base = (QElemType*)malloc(sizeof(QElemType));//分配数组空间

        if(!Q.base) exit(OVERFLOW); //存储分配失败

        Q.front =Q.rear =0;// 头指针置为 0 队列为空

        return OK;

}

2.3.3 循环队列的求队列长度

int QueueLengh(SqQueue Q){

        return ((Q.rear-Q.front+MAXSIZE)%MAXSIZE);

}

2.3.4 循环队列入队

 Status EnQueue(SqQueue &Q,QElemType e){

         if((Q.rear+1)%MAXSIZE==Q.front) return ERROR; //队满

        Q.base[Q.rear]=e; //新元素入队尾

        Q.rear = (Q.rear+1)%MAXSIZE; //队尾指针+1

        return OK;

}

2.3.5  循环对列的出队

Status DeQueue(SqQueue &Q,QElemType &e){

        if(Q.rear==Q.front) return ERROR; //队空

        e = Q.base[Q.rear]; //新元素入队尾

        Q.front = (Q.front+1)%MAXSIZE; //队尾指针+1

        return OK;

}

2.3.6 取队头元素

SElemType GetHead(SqQueue Q){

        if(Q.front!=Q.rear)// 队列不为空

                return Q.base[Q.front]; // 返回对头指针元素的值 队头指针不变

}

2.4:链队的表示和实现

关于链队的一些重点

1:链队(链式队列)和循环队列(顺序队式)是队列的不同的表示方式。那么什么时候使用队列什么时候使用链队?

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

2:链队和栈链的不同?

链队先进先出(FIFO)和栈链后进先出(LILO),类比银行排队(链队),弹夹子弹出膛(栈链)

3:链队和栈链的相似之处

栈和队列是限定插入和删除只能在表的"端点”进行的线性表


 

2:链式队列的表示和基本操作

链式队列的表示

 

(Q.front指向头结点,Q.rear指向尾结点)

心中有图 撸码自然神

一:链队的类型表示:

typedef int Status;

typedef int QElemType;

typedef struct Qnode{ //创建节点类型= data数据域+*next指针域

        QElemType data;

        struct Qnode *next;

}QNode,*QueuePtr;//别名

//补:  *QueuePtr指向该节点的指针类型

//引:所以Q.front是什么类型 ,有什么用?

//Q代表什么?

typedef struct{

        QueuePtr front;

        QueuePtr rear

}LinkQueue;//由两个结构体指针组成了链式队列

二:链队列的指针变化状况

基本操作的本质就是不同指针的不同变化状况

 心中有图 撸码自然神

三:链队的操作

1 初始化

Status initQueue(LinkQueue &Q){

          Q.front=Q.rear=(QueuePtr*)malloc(sizeof(QNode));

        // 或者Q.front=Q.rear=new QNode;

          Q.front->next=NULL;

          return OK;

}

2 链队的销毁

Status DestroyQueue(LinkQueue &Q){
    while(Q.front){

        QueuePtr p;
        p=Q.front->next;
        free(Q.front);
        Q.front=p;
    }
    return OK;
}

3 链队列入队

 Status EnLinkQueue(LinkQueue &Q,QElemType e){
    QNode *p=new QNode;//或者p=(QueuePtr)malloc(sizeof(QNode));
    if(!p)exit(OVERFLOW);
    p->data=e;
    p->next=NULL;
    Q.rear->next=p;
    Q.rear=p;
    return OK;
}

4:链队列出队

 在头结点上操作

Status DeLinkQueue(LinkQueue &Q,QElemType &e){
    if(Q.front==Q.rear)return ERROR;
   // QNode *p=new QNode;
     QueuePtr p;
    p=  Q.front->next;
    e=p->data;
    Q.front->next=p->next;
    if(Q.rear==p)
        Q.rear=Q.front;
    delete p;
    return OK;
}

5:算链队列的对头元素

了解队头是:Q.front还是Q.front->next?

Q.front:头结点 || Q.front->next :队头元素x 所以:对头元素x在头结点的下一位置上

Status GetHead(LinkQueue &Q,QElemType &e){
    if(Q.front==Q.rear)return ERROR;
    e=Q.front->next->data;
    return OK;    
}

实例练习:行排队叫号系统

编写程序实现银行排队叫号系统,采用链队列作为存储结构。

//编写程序实现银行排队叫号系统,采用链队列作为存储结构。
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define TRUE 1
#define FALSE 0
#define MAX_QSIZE 30
typedef int Status;
typedef int QElemType;
typedef struct Qnode
{
    QElemType data;
    struct Qnode * next;
}QNode, *QueuePtr;//创建节点类型
typedef  struct Queue{
  QueuePtr   front ; //队首指针
  QueuePtr   rear ; //队尾指针
  }LinkQueue;
Status InitLinkQueue(LinkQueue &Q);//对链队列进行初始化
Status EnLinkQueue(LinkQueue &Q,QElemType e);//入队
Status DeLinkQueue(LinkQueue &Q,QElemType &e);//出队
Status QueueEmpty(LinkQueue Q);//判断队空

/* 请在这里填写答案 */
Status InitLinkQueue(LinkQueue &Q){
    Q.front =Q.rear =(QNode*)malloc(sizeof(QNode));
    Q.front->next= NULL;
    return OK;
}
Status EnLinkQueue(LinkQueue &Q,QElemType e){
    QNode *p=new QNode;
    if(!p)exit(OVERFLOW);
    p->data=e;
    p->next=NULL;
    Q.rear->next=p;
    Q.rear=p;
    return OK;
}
Status DeLinkQueue(LinkQueue &Q,QElemType &e){
    if(Q.front==Q.rear)return ERROR;
   // QNode *p=new QNode;
       QueuePtr p;
    p=  Q.front->next;
    e=p->data;
    Q.front->next=p->next;
    if(Q.rear==p)
        Q.rear=Q.front;
    delete p;
    return OK;
}
int main()
{
    QElemType no=1;
    QElemType callno;
    int select,flag=1;
    LinkQueue qu;
    InitLinkQueue(qu);
    while(flag==1)
    {
        //printf("1:排队2:叫号0:退出 请选择:");
        scanf("%d",&select);
        switch(select)
        {
        case 1: printf("您的序号为:%d\n",no);
                EnLinkQueue(qu,no);  //no入队
                no++;
                break;
        case 2: if(DeLinkQueue(qu,callno)==ERROR)
                    printf(">>没有排队的客户!\n");
            else//队不空
                printf(">>请%d号办理业务\n",callno);
                break;
        case 0:flag=0;
        }
    }
    return 0;
}

  • 10
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值