zoukankan      html  css  js  c++  java
  • 数据结构之守规矩的先进先出的队列(二)

    一、队列的概念

      队列是一种特殊的线性表,严格按照“先进先出”的原则。

    二、队列基础

      队列和栈一样只允许在断点处插入和删除元素,其基本操作包括以下:

      (1)InitQueue(&Q);    //初始化一个空队列

      (2)DestroyQueue(&Q);   //清空队列

      (3)QueueEmpty(&Q);  //队列判空

      (4)QueueLength(&Q); //求队列的长度

      (5)GetHead(Q,&e); //取对头元素

      (6)EnQueue(&Q,e); //插入新元素

      (7)DeQueue(&Q,&e); //删除队头元素

      (8)QueueTraverse(Q,visit()); //每个元素调用visit()函数

      队列的分类:链队列和循环队列

      C语言定义链队的格式

    typedef struct QNode
    {
        ElemType data;
        struct Qnode *next;
    }QNode,*QueuePtr;
    typedef struct
    {
        QueuePtr front;  //对头指针,指向头元素
        QueuePtr rear;   //队尾指针,指向队尾元素
    }LinkQueue;

       可以采用顺序表来存储定义循环队列,具体代码如下:

    #define MAXQSIZE 100    //最长队列长度
    typedef struct {
        ElemType *base;     //存储空间
        int front;          //头指针,指向队列的头元素
        int rear;           //尾指针,指向队列元素的下一个位置
    }SqQueue;

       队列的基本操作

      (1)初始化队列Q的目的是创建一个队列

    void InitQueue(QUEUE *Q)
    {
        Q->front = -1;
        Q->rear = -1;
    }

       (2)入队的目的是将一个新元素添加到队尾,相当于队列最后队列等候。

    void EnQueue(QUEUE *Q, Elemtype elem){
        if ((Q->rear+1)%MAX_QUEUE==Q->front)
        {
            exit(OVERFLOW);
        }
        else{
            Q->rear = (Q->reasr + 1) % MAX_QUEUE;
            Q->elem[Q->rear] = elem;
        }
    }

      (3)出队的目的是取出对头元素,并同时删除该元素,使后一个元素成为对头元素。

    void DeQueue(QUEUE *Q, Elemtype *elem)
    {
        if (QueueEmpty(*Q))
        {
            exit("Queue is empty.");
        }
        else
        {
            Q->front = (Q->front + 1) % MAX_QUEUE;
            *elem = Q->elem[Q->front];
        }
    }

      (4)获取队列的第一个元素,即将队头的元素取出,不删除该元素,队头仍然是该元素。

    void GetFront(QUEUE *Q, Elemtype *elem)
    {
        if (QueueEmpty(*Q))
        {
            exit("Queue is empty.");
        }
        else
        {
            *elem = Q->elem[ (Q->front + 1) % MAX_QUEUE];
        }
    }

      (5)判断队列Q是否为空

    int QueueEmpty(Queue Q)
    {
        if (Q.front==Q.rear)
        {
            return TRUE;
        }
        else
        {
            return FALSE;
        }
    }

      队列的链式存储

      在C语言中,链式队列的基本操作算法如下:

      (1)初始化队列Q,算法代码如下:

    void InitQueue(QUEUE *Q)
    {
        Q->front = (LINKLIST*)malloc(sizeof(LINKLIST));
        if (Q->front==NULL) 
        {
            exit(ERROR);
        }
        Q->rear = Q->front;
    }

      (2)入队操作

    void EnQueue(QUEUE *Q, Elemtype elem){
        s = (LINKLIST*)malloc(sizeof(LINKLIST));
        if (!s)
        {
            exit(ERROR);
        }
        s->elem = elem;
        s->next = NULL;
        Q->rear->next = s;
        Q->rear = s;
    }

      (3)出队操作

    void DeQueue(QUEUE *Q, Elemtype *elem)
    {
        if (QueueEmpty(*Q))
        {
            exit(ERROR);
        }
        else
        {
            *elem = Q->front->next->elem;
            s = Q->front->next;
            Q->front->next = s->next;
            Q->front = (Q->front + 1) % MAX_QUEUE;
            free(s);
        }
    }

      (4)获取队头元素

    void GetFront(QUEUE Q, Elemtype *elem)
    {
        if (QueueEmpty(Q))
        {
            exit(ERROR);
        }
        else
        {
            *elem = Q->front->next->elem;
        }
    }

       (5)判断队列Q是否为空

    void QueueEmpty(QUEUE Q)
    {
        if (Q->front==Q->rear)
        {
            return TRUE;
        }
        else
        {
            return FALSE;
        }
    }

     三、实例演练

      “新增顾客”编号问题

      代码实现:

    /*
        构建一个完整循环队列
    */
    #include "stdio.h"
    #include "malloc.h"
    #define QUEUEMAX 15
    //typedef DATA;
    typedef struct  
    {
        DATA data[QUEUEMAX]; //队列数组
        int head;
        int tail;
    }CycQueue;
    CycQueue *CycQueueInit()
    {
        CycQueue *q;
        if (q=(CycQueue *)malloc(sizeof(CycQueue)))
        {
            q->head = 0;//设置队头
            q->tail = 0;//设置队尾
            return q;
        }
        else
        {
            return NULL;//返回空
        }
    }
    
    void CycQueueFree(CycQueue *q)  //释放队列
    {
        if (q!=NULL)  
            free(q);
    }
    
    int CycQueueIsEmpty(CycQueue *q) //队列是否为空
    {
        return (q->head == q->tail);
    }
    
    int CycQueueIsFull(CycQueue *q)  //队列是否为满
    {
        return ((q->tail + 1) % QUEUEMAX == q->head);
    }
    
    int CycQueueIn(CycQueue *q, DATA data) //入队
    {
        if ((q->tail + 1) % QUEUEMAX == q->head)
        {
            printf("队列满了!
    ");
            return 0;
        }
        else
        {
            q->tail = (q->tail + 1) % QUEUEMAX;//求列尾序号
            q->data[q->tail] = data;
            return 1;
        }
    }
    
    DATA *CycQueueOut(CycQueue *q)  //循环队列出队函数
    {
        if (q->head==q->tail)  //队列为空
        {
            printf("队列为空了!
    ");
            return NULL;
        }
        else
        {
            q->head = (q->head + 1) % QUEUEMAX;
            return &(q->data[q->head]);
        }
    }
    
    int CycQueueLen(CycQueue *q)  //获取队列长度
    {
        int n;
        n = q->tail - q->head;
        if (n<0)
        {
            n = QUEUEMAX + n;
        }
        return n;
    }
    
    DATA *CycQueuePeek(CycQueue *q) //获取队列第一个位置的数据
    {
        if (q->head==q->tail)
        {
            printf("队列已经空了!
    ");
            return NULL;
        }
        else
        {
            return &(q->data[(q->head + 1) % QUEUEMAX]);
        }
    }
    
    
    ##############################################
    #include "stdlib.h"
    #include "stdio.h"
    #include "time.h"
    #include "xuncao.h"
    
    typedef struct 
    {
        int num;    //顾客编号
        long time;  //进入队列的时间
    
    }DATA;
    
    int num;  //顾客序号
    void add(CycQueue *q) //新增顾客排列
    {
        DATA data;
        if (!CycQueueIsFull(q))
        {
            data.num = ++num;
            data.time = time(NULL);
            CycQueueIn(q, data);
        }
        else
        {
            printf("
    排队的人实在是太多了,请您稍候再排队!
    ");
        }
    }
    
    void next(CycQueue *q)  //通知下一位顾客准备
    {
        DATA *data;
        if (!CycQueueIsEmpty(q))  //若队列不为空
        {
            data = CycQueueOut(q); //取队列头部的数据
            printf("
    欢迎编号为%d的顾客到柜台办理业务!
    ", data->num);
        }
        if (!CycQueueIsEmpty(q))  //若队列不为空
        {
            data = CycQueuePeek(q); //取队列中指定位置的数据
            printf("请编号为%d的顾客做好准备,马上将为您办理业务!
    ", data->num);
        }
    }
    
    int main()
    {
        CycQueue *queuel;
        int i, n;
        char select;
        num = 0;  //顾客序号
        queuel = CycQueueInit();//初始化队列
        if (queuel==NULL)
        {
            printf("创建队列时出错误!
    ");
            getch();
            return 0;
        }
        do 
        {
            printf("
    请选择具体操作:
    ");
            printf("1.新到顾客
    ");
            printf("2.下一个顾客
    ");
            printf("0.退出
    ");
            fflush(stdin);
            select = getch();
            switch (select)
            {
            case'1':
                add(queuel);
                printf("
    现在共有%d位顾客在等候!
    ", CycQueueLen(queuel));
                break;
            case'2':
                next(queuel);
                printf("
    现在共有%d位顾客在等候!
    ", CycQueueLen(queuel));
                break;
            case'0':
                break;
            }
    
        } while (select!='0');
        CycQueueFree(queuel); //释放队列
        system("pause");
        return 0;
    }
    代码实现
  • 相关阅读:
    Mysql:Error Code 1235,This version of MySQL doesn’t yet support ‘LIMIT & IN/ALL/ANY/SOME 错误解决
    java 发送带Basic Auth认证的http post请求
    spring-boot 加载本地静态资源文件路径配置
    mac上使用终端生成RSA公钥和密钥
    mysql 查看正在运行的进程
    mysql中You can’t specify target table for update in FROM clause错误解决方法
    Redis的三种启动方式
    Redis在Mac下的安装与使用方法
    Linux vi中查找字符内容的方法
    spring boot 之@JsonView 简单介绍
  • 原文地址:https://www.cnblogs.com/hxf175336/p/9866049.html
Copyright © 2011-2022 走看看