数据结构 第6节 队列

一、什么叫做队列❓

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

二、队列的分类
  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 
#include 
#include 

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节 队列)