C语言队列的数组实现(源码笔记)

queue.h

typedef int ElementType;
/* START: fig3_57.txt */
#ifndef _Queue_h
#define _Queue_h

struct QueueRecord;
typedef struct QueueRecord *Queue;

int IsEmpty(Queue Q);

int IsFull(Queue Q);

Queue CreateQueue(int MaxElements);

void DisposeQueue(Queue Q);

void MakeEmpty(Queue Q);

void Enqueue(ElementType X, Queue Q);

ElementType Front(Queue Q);

void Dequeue(Queue Q);

ElementType FrontAndDequeue(Queue Q);

#endif  /* _Queue_h */
/* END */

queue.c

#include "queue.h"
#include "fatal.h"
#include <stdlib.h>

#define MinQueueSize ( 5 ) // 队列中存储数据的数组最小也得能存5个

struct QueueRecord
{
    int Capacity; // 容量
    int Front; // 队列头
    int Rear; // 队列尾
    int Size; // 尺寸
    ElementType *Array;
};

/* START: fig3_58.txt */
int
IsEmpty(Queue Q)
{
    return Q->Size == 0;
}

/* END */

int
IsFull(Queue Q)
{
    return Q->Size == Q->Capacity; // 这里这样判断的原因是队列可以越过Capacity - 1这个索引,并且判断的标准是Size,所以是循环数组
}

Queue
CreateQueue(int MaxElements)
{
    Queue Q;

/* 1*/      if (MaxElements < MinQueueSize)
/* 2*/          Error("Queue size is too small");

/* 3*/      Q = malloc(sizeof(struct QueueRecord));
/* 4*/      if (Q == NULL)
/* 5*/          FatalError("Out of space!!!");

/* 6*/      Q->Array = malloc(sizeof(ElementType) * MaxElements);
/* 7*/      if (Q->Array == NULL)
/* 8*/          FatalError("Out of space!!!");
/* 9*/      Q->Capacity = MaxElements;
/*10*/      MakeEmpty(Q);

/*11*/      return Q;
}

/* START: fig3_59.txt */
void
MakeEmpty(Queue Q)
{
    Q->Size = 0; // 初始元素个数为0
    Q->Front = 1; // 头节点初始化为1
    Q->Rear = 0; // 尾节点初始化为0
}

/* END */

void
DisposeQueue(Queue Q)
{
    if (Q != NULL)
    {
        free(Q->Array);
        free(Q);
    }
}

/* START: fig3_60.txt */

// 这两个是入队的例程
static int
Succ(int Value, Queue Q)
{
    if (++Value == Q->Capacity)
        Value = 0;
    return Value;
}
void
Enqueue(ElementType X, Queue Q)
{
    if (IsFull(Q))
        Error("Full queue");
    else
    {
        Q->Size++;
        Q->Rear = Succ(Q->Rear, Q);
        Q->Array[Q->Rear] = X; // 这里是向队尾追加元素
    }
}

/* END */


// 返回队列的首元素
ElementType
Front(Queue Q)
{
    if (!IsEmpty(Q))
        return Q->Array[Q->Front];
    Error("Empty queue");
    return 0;  /* Return value used to avoid warning */
}

// 出队
void
Dequeue(Queue Q)
{
    if (IsEmpty(Q))
        Error("Empty queue");
    else
    {
        Q->Size--;
        Q->Front = Succ(Q->Front, Q); // 因为遵循先进先出原则,所以队头要这样处理
    }
}


// 在出队的同时返回该元素
ElementType
FrontAndDequeue(Queue Q)
{
    ElementType X = 0;

    if (IsEmpty(Q))
        Error("Empty queue");
    else
    {
        Q->Size--;
        X = Q->Array[Q->Front];
        Q->Front = Succ(Q->Front, Q);
    }
    return X;
}

testque.c(main.c)

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

int main()
{
    Queue Q;
    int i;

    Q = CreateQueue(12);

    // 先入队10个元素,从0~9
    for (i = 0; i < 10; i++)
        Enqueue(i, Q);

    // 打印队列里面的元素,打印完之后出队
    while (!IsEmpty(Q))
    {
        printf("%d\n", Front(Q));
        Dequeue(Q);
    }

    // 再次插入10个元素
    for (i = 0; i < 10; i++)
        Enqueue(i, Q);

    // 打印
    while (!IsEmpty(Q))
    {
        printf("%d\n", Front(Q));
        Dequeue(Q);
    }

    DisposeQueue(Q);
    return 0;
}

fatal.h

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

#define Error(Str)        FatalError( Str )
#define FatalError(Str)   fprintf( stderr, "%s\n", Str ), exit( 1 )

运行结果:

posted @ 2020-09-20 00:56  模糊计算士  阅读(283)  评论(0编辑  收藏  举报