队列的顺序存储

用循环数组来,描述一个队列。
要搞清楚两件事:

  1. 何时为空
  2. 何时为满

头文件

#ifndef _HEAD_H
#define _HEAD_H
#define MINSIZE 5

typedef int ElementType;
typedef struct node* Queue;

typedef struct node{
    ElementType* arrayQueue;
    int front; //队头
    int rear; //队尾
    int length; //队列长度
}Node;

Queue CreateQueue(void);
void Display(Queue q); 
void MakeEmpty(Queue q); 
int IsEmpty(Queue q); 
int IsFull(Queue q); 
void Free(Queue q); 
int LengthQueue(Queue q); 
void AddElementType(Queue q, ElementType x); 
ElementType DeleteElementType(Queue q); 
void clean(void);

#endif 

front表示队头的第一个元素,rear表示队尾的第一个空位置。
当队为空时,front和rear相等。(为什么不是同时等于0,因为front在一个元素出队后就会后移,不一定就永远在0位置。)
在这里插入图片描述

因为队列在删除时,会删除数组下标最小的那个元素,那个位置会空出来。当队尾超过最大下标时,再加入元素就可以用再用前面空出来的位置,这样就成了一个循环数组。
在这里插入图片描述
那什么时候是队满呢?。
有两种判断方式,

  1. 当这个数组满了,队就满了。这时用一个flag来标志。当front = rear且flag = 1时是满,当front = rear且flag = 0时是空。
  2. 当整个数组只有一个空位时就满,这样避免与队空相同。也就是rear后面就是front。

讨论第二种判断方式
在这里插入图片描述
这个图可以用rear + 1 = front来表示。那是否就可以用rear + 1 = front来表示队满呢?
看下面这个图:
在这里插入图片描述
显然这种情况也是队满,但是却不能用rear + 1 = front来表示了。

怎么办?有没有一种通用的表达式?

有,只要超过后对数组长度取余即可。

判断队满:(rear + 1) % arraylength = front

队长也是用这种方法。

队长=((rear - front) + arraylength)% arraylength

这种队列在此还有很多种细节来考,比如rear表示的是最后一个元素,而不是后一个空位。空两位时队满等等。

重点是搞清楚,判断队空的条件与判断队满的条件。

操作集

#include"head.h"
#include <stdlib.h>
#include <stdio.h>

Queue CreateQueue(void)
{
    printf("输入队列最大容量:");
    int size;
    while(scanf("%d", &size))
    {
        if (size >= MINSIZE)
            break;
        else
            printf("请输入一个不小于%d的数:", MINSIZE);
    }
    Queue q = (Queue)malloc(sizeof(Node));
    if (q == NULL)
    {
        printf("out of space!\n");
        exit(EXIT_FAILURE);
    }
    q->arrayQueue = (ElementType*)malloc(size * sizeof(ElementType));
    if (q->arrayQueue == NULL)
    {
        printf("out of space!\n");
        exit(EXIT_FAILURE);
    }
    q->front = 0;
    q->rear = 0;
    q->length = size;

    return q;
}
void MakeEmpty(Queue q)
{
    q->front == q->rear == 0;
}
int IsEmpty(Queue q)
{
    return q->front == q->rear;//队空
}
int IsFull(Queue q)
{
    return (q->rear + 1) % (q->length) == q->front;//队满
}
int LengthQueue(Queue q)
{
    return ((q->rear - q->front) + q->length) % (q->length); //队长
}
void Display(Queue q)
{
    if (q == NULL)
    {
        printf("the point is NULL\n");
        return ;
    }
    printf("队列长度为%d:", LengthQueue(q));
    if (IsEmpty(q))
    {
        printf("空队列\n");
        return ;
    }
    else
    {
        for (int i = q->front; i < q->rear; i++)
        {
            printf("%d", q->arrayQueue[i]);
            if (i != q->rear - 1)
                printf("<-");
        }
        printf("\n");
    }
}
void Free(Queue q)
{
    free(q->arrayQueue);
    q->arrayQueue = NULL;
    free(q);
}
void AddElementType(Queue q, ElementType x)
{
    if (q == NULL)
    {
        printf("the point is NULL\n");
        exit(EXIT_FAILURE);
    }
    if (IsFull(q))
    {
        printf("不能加入刚才这个元素,因为队列已满\n");
        return ;
    }
    q->arrayQueue[q->rear] = x;
    q->rear = (q->rear + 1) % (q->length);
}
ElementType DeleteElementType(Queue q)
{
    if (q == NULL)
    {
        printf("the point is NULL\n");
        exit(EXIT_FAILURE);
    }
    if (IsEmpty(q))
    {
        printf("队列为空\n");
        return -1;
    }
    ElementType data = q->arrayQueue[q->front];
    q->front = (q->front + 1) % (q->length);
    return data;
}
void clean(void)
{
    while(getchar() != '\n')
        continue;
}

主函数

#include <stdio.h>
#include "head.h"

int main(void)
{
    printf("创建\n");
    printf("*********************************************\n");
    Queue q = CreateQueue();
    Display(q);
    
    printf("入队\n");
    printf("*********************************************\n");
    ElementType data;
    printf("请输入要入队的元素(非数字结束):");
    while(scanf("%d", &data))
    {
        printf("请输入要入队的元素(非数字结束):");
        AddElementType(q, data);
    }
    Display(q);
    
    printf("出队\n");
    printf("*********************************************\n");
    data = DeleteElementType(q);
    if (data != -1)
        printf("删除的元素:%d\n", data);
    Display(q);
    
    printf("释放,指针置空\n");
    printf("*********************************************\n");
    Free(q);
    q = NULL;
    Display(q);

    return 0;
}   

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CCPigSnail

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值