C语言链表实现队列

课本上只给了队列的数组实现,关于链表实现的留做了作业,现实现如下:

queueli.h

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

struct Node;
struct QNode;
typedef struct Node *PtrToNode; // 指向Node节点的指针
typedef struct QNode *Queue; // 队列头,也是指向QNode节点的指针

int IsEmpty(Queue Q);

Queue CreateQueue(void);

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 */

queueli.c

#include "queueli.h"
#include "fatal.h"
#include <stdio.h>


// 节点
struct Node
{
    ElementType Element;
    PtrToNode Next;
};

struct QNode
{
    PtrToNode rear; // 指向队尾节点
    PtrToNode front; // 指向对头节点
};

// 判断队列是否为空
int IsEmpty(Queue Q)
{
    return (Q->front == NULL);
}

Queue CreateQueue(void)
{
    Queue Q;
    Q = malloc(sizeof(struct QNode));
    if (Q == NULL)
        FatalError("Out of space!!!"); // 空间用尽警告
    Q->front = NULL;
    Q->rear = NULL;
    MakeEmpty(Q); // 还是感觉有些多此一举
    return Q;
}

// 创建一个空队列
void MakeEmpty(Queue Q)
{
    if (Q == NULL)
        Error("Must use CreateQueue first");
    else
        while (!IsEmpty(Q))
            Dequeue(Q);
}

// 清除队列
void DisposeQueue(Queue Q)
{
    if (Q != NULL)
    {
        MakeEmpty(Q);
        free(Q);
    }
}

// 入队操作
void Enqueue(ElementType X, Queue Q)
{
    PtrToNode TmpCell;

    TmpCell = malloc(sizeof(struct Node));
    if (TmpCell == NULL)
        FatalError("Out of space!!!");
    TmpCell->Element = X;
    TmpCell->Next = NULL;
    if (Q->rear == NULL)
    { // 此时队列为空
        Q->rear = TmpCell;
        Q->front = TmpCell;
    } else { // 不为空
        Q->rear->Next = TmpCell; // 将节点入队
        Q->rear = TmpCell; // rear 仍然保持最后
    }
}

// 取出队首元素
ElementType Front(Queue Q)
{
    if (!IsEmpty(Q))
        return Q->front->Element;
    Error("Empty queue");
    return 0; // Return value used to avoid warning
}

// 出队操作
void Dequeue(Queue Q)
{
    PtrToNode FrontCell;
    if (IsEmpty(Q))
        Error("Empty queue");
    else
    {
        FrontCell = Q->front;
        if (Q->front == Q->rear) { // 只有一个元素
            Q->front = Q->rear = NULL;
        } else { // 有多个元素时
            Q->front = Q->front -> Next; // 先将front指向队首元素的下一个元素
        }
        free(FrontCell); // 不要忘了释放出对的节点
    }
}

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

    if (IsEmpty(Q))
        Error("Empty queue");
    else
    {
        X = Front(Q);
        Dequeue(Q);
    }
    return X;
}

测试函数 main.c(testqueli.c)

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

int main()
{
    Queue Q;
    int i;

    Q = CreateQueue();

    // 先入队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-24 01:25  模糊计算士  阅读(199)  评论(0编辑  收藏  举报