美文网首页数据结构
数据结构 第6节 队列

数据结构 第6节 队列

作者: 小超_8b2f | 来源:发表于2019-07-20 12:15 被阅读0次
    一、什么叫做队列❓

    一种可以实现【先进先出】的存储结构

    二、队列的分类
    1. 链式队列

      链式队列示意图:链表形式实现,front即链表的pHead,rear:臀,屁股
      提示
      一头进一头出,先进先出。实现参考链表。
      front指向第一个有效元素
      rear指向最后一个有效元素的下一个元素,rear本身是无数据元素,类似于链表的pHead
    2. 静态(数组)队列

    • 静态队列通常必须是循环队列
    • 学习循环队列必须搞懂的7个问题。
      1. 为什么必须是循环队列?

      2. 循环队列需要几个参数确定?
        1)front :队列头,先进的元素,先出的元素

        1. rear : 队列尾,臀。无数据,只起到方便操作作用
      3. 循环队列各个参数的含义?

        • front 队列头的含义
        • rear
        • 2个参数不同场合有不同的含义,建议初学者先记住,然后慢慢体会。
        • 队列初始化: front 和 rear 皆为0
        • 队列非空:
          front:队列的第一个有效元素
          rear:队列的最后一个有效元素的后一个值为NULL的元素
        • 队列为空:font和rear的值相等,但不一定是0️⃣
      4. 循环队列入队伪算法讲解


        image.png
      5. 循环队列出队伪算法讲解

      • 入队两步骤:
        1. 将值存入r所代表的位置
        2. 错误的写法r = r + 1;
          正确的写法:r = (r + 1) % 数组的长度
    • 出队步骤:
      1. 保存front的值 (如果有必要的话)
      2. 错误的写法f = f + 1;
        正确的写法:f = (f + 1) % 数组的长度
    1. 如何判定循环队列是否为空
      如果front 和rear的值相等,则该队列肯定为空
    2. 如何判断循环队列已满


      队列满时front 和 rear在同一位置,对列为空时也在同一位置
    判断方式
    • 方式一:(❌)
      当元素个数 = 数组长度时,即:front = rear时,标记为满。
    • 方式二:(常用)(✅)
      当元素个数 = 数组长度 - 1 时,即:front和rear相邻时,标记为满。

    解决方式
    方式一  (不采用❌)

    • 新增加一长度字段来记录元素个数。
      麻烦,每次新增、删除时都需要取维护

    方式二  (采用✅)

    • 数组少用一个元素,
    • 判断front 和 rear 挨着,并且是rear的next元素是front
    • 而不是front的下一个元素是rear(只剩下一个元素)
    if( (rear + 1) % 数组长度 == front)
    {
      已满
    } 
    else 
    {
      不满
    }
    

    队列代码实现

    #include <stdio.h>
    #include <stdlib.h>
    #include <malloc.h>
    
    typedef struct ArrayQueue {
        int * pBase;  //数据域
        int front;    //指针域
        int rear;     //臀
    } QUEUE, * PQUEUE;
    
    
    void init(PQUEUE);
    bool en_queue(PQUEUE, int);
    bool out_queue(PQUEUE pQ,int * pVal);
    void show(PQUEUE);
    bool isEmpty(PQUEUE pQ);
    bool isFull(PQUEUE);
    void show(PQUEUE pQ);
    
    int main(void) {
        QUEUE q;
        init(&q);
        en_queue(&q,1);
        en_queue(&q,2);
        en_queue(&q,3);
        en_queue(&q,4);
        en_queue(&q,5);
        en_queue(&q,6);
        en_queue(&q,7);
        en_queue(&q,8);
        show(&q);
        int i;
        printf("开始出队:\n");
        out_queue(&q,&i);
        show(&q);
        printf("开始出队:\n");
        out_queue(&q,&i);
        show(&q);
        return 0;
    }
    
    
    void init(PQUEUE pQ) {
        pQ->pBase = (int *)malloc(sizeof(int) * 6);
        pQ->front = 0;
        pQ->rear = 0;
    }
    
    
    bool en_queue(PQUEUE pQ, int val) {
        if(isFull(pQ))
        {
            printf("插入值:%d时 队列已满\n", val);
            return false;
            exit(-1);
        }
        else
        {
            pQ->pBase[pQ->rear] = val;
            pQ->rear++;
            return true;
        }
    }
    
    bool out_queue(PQUEUE pQ,int * pVal) {
        if(isEmpty(pQ))
        {
            return false;
        }
        else
        {
            *pVal = pQ->pBase[pQ->front];
            pQ->front = (pQ->front + 1) % 6;
            return true;
        }
    }
    
    bool isEmpty(PQUEUE pQ) {
        if(pQ->front == pQ->rear)
           return true;
        else
           return false;
    }
    
    
    bool isFull(PQUEUE pQ) {
        if((pQ->rear + 1) % 6 == pQ->front)
            return true;
        else
            return false;
    }
    
    void show(PQUEUE pQ) {
        int i = pQ->front;
        while(i != pQ -> rear) {
            printf("%d ", pQ -> pBase[i]);
            i = (i+1) % 6;
        }
        printf("\n");
        return;
    }
    

    相关文章

      网友评论

        本文标题:数据结构 第6节 队列

        本文链接:https://www.haomeiwen.com/subject/ilajlctx.html