链式队列的定义及其相关功能的实现

链式队列

链式栈:我们使用的是无头单向链表,无头单向链表的头为栈顶,对无头单向链表进行头插头删。
链式队列:我们使用的是有头单向链表,有头单向链表的头结点为队头,终端结点为队尾。对有头单向链表进行头删、尾插。
1.概念
队列的链式存储结构,其实就是线性表的单链表,只不过它是操作受限的线性表。它只能尾进头出而已,将其简称为链式队列。
为了操作上的方便,我们将队头指针指向链式队列的头结点,而队尾指针指向终端结点,如下图所示。

空队列时,frontrear都指向头结点,如下图所示:

 接口实现

链式队列函数定义

初始化函数LQ *LQInit();
入队函数int LQInQueue(LQ *PQ, LQDataType data);
出队函数(返回出队数据)LQDataType LQOutQueue(LQ *PQ);
计算长度函数(返回int类型长度)int LQLength(LQ *PQ);
打印(显示内容)函数void LQPrint(LQ PQ);
清空函数void LQClear(LQ *PQ);

创建空的链式队列

  1. 开辟空间存放操作链式队列的结构体
  2. 在给结构体成员(队头指针front和队尾指针rear)进行初始化的时候开辟空间存放头结点

        让队头指针frontrear同时指向这段空间。

        3.对头结点进行初始化,让其指针域指向NULL

 链式队列入列

 LinkQueue.c文件(函数定义)

#include "LinkQueue.h"
LQ *LQInit()
{
    LQ *PQ = (LQ *)malloc(sizeof(LQ));
    if (NULL == PQ)
    {
        printf("LQInit failed, PQ malloc err.\n");
        return NULL;
    }
    PQ->front = PQ->rear = (LL)malloc(sizeof(LLN));
    if (NULL == PQ->front)
    {
        printf("LQInit failed, PQ->front or PQ->rear malloc err.\n");
        return NULL;
    }
    PQ->front->next = NULL;
    return PQ;
}

int LQInQueue(LQ *PQ, LQDataType data)
{
    LL PNew = (LL)malloc(sizeof(LLN));
    if (NULL == PNew)
    {
        printf("LQInQueue failed, PNew malloc err.\n");
        return -1;
    }
    PNew->data = data;
    PNew->next = NULL;
    PQ->rear->next = PNew;
    PQ->rear = PNew;
    return 0;
}

LQDataType LQOutQueue(LQ *PQ)
{

    if (PQ->front == PQ->rear)
    {
        printf("LQOutQueue failed, LQ is empty.\n");
        return -1;
    }
    LL PDel = PQ->front;
    PQ->front = PQ->front->next;
    free(PDel);
    PDel = NULL;
    return PQ->front->data;
}

int LQLength(LQ PQ)
{
    int len = 0;
    if (PQ.front == PQ.rear)
    {
        return 0;
    }
    else
    {
        while (PQ.front->next)
        {
            len++;
            PQ.front = PQ.front->next;
        }
        return len;
    }
}

void LQPrint(LQ PQ)
{
    if (PQ.front == PQ.rear)
        printf("队列为空\n");
    else
    {
        printf("队列为:");
        while (PQ.front->next)
        {

            printf("%d ", PQ.front->next->data);
            PQ.front = PQ.front->next;
        }
        putchar(10);
    }
}

void LQClear(LQ *PQ)
{
    while(PQ->front != PQ->rear)
        LQOutQueue(PQ);
}

LinkQueue.h文件

头文件:存放函数声明

链式队列结构体定义(内含数据、头指针、尾指针)

头指针、尾指针的结构体定义(单链表结点)

内含数据域data和指针域next

#ifndef _LINKQUEUE_H_
#define _LINKQUEUE_H_

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

typedef int LQDataType;

typedef struct LinkListNode
{
    LQDataType data;
    struct LinkListNode *next;
} LLN, *LL;

typedef struct LinkQueue
{
    LL front;
    LL rear;
} LQ;

LQ *LQInit();
int LQInQueue(LQ *PQ, LQDataType data);
LQDataType LQOutQueue(LQ *PQ);
int LQLength(LQ PQ);
void LQPrint(LQ PQ);
void LQClear(LQ *PQ);

#endif

test.c文件(主函数以及相关函数的调用)

#include "LinkQueue.h"
int main(int argc, char const *argv[])
{
    LQ *PQ = LQInit();
    LQInQueue(PQ, 10);
    LQInQueue(PQ, 20);
    LQInQueue(PQ, 30);
    LQPrint(*PQ);
    LQOutQueue(PQ);
    // for (int i = 0; i < 3; i++)
    // {
    //     int data = LQOutQueue(PQ);
    //     printf("出队数据是%d\n", data);
    // }
    printf("队列长度为%d\n", LQLength(*PQ));
    LQPrint(*PQ);
    LQClear(PQ);
    printf("队列长度为%d\n", LQLength(*PQ));

    free(PQ->front);        //如果进行了LQClear操作,则只需要释放PQ->front或者PQ->rear,否则二者都需要释放
    PQ->front = NULL;
    free(PQ);
    PQ = NULL;
    return 0;
}

运行结果

makefile文件

CC=gcc
OBJS=test.o LinkQueue.o
CFLAGS=-c -g -Wall
test:$(OBJS)
	$(CC) -o $@ $(OBJS)
%.o:%.c
	$(CC) $(CFLAGS) $< -o $@

.PHONY:clean
clean:
	$(RM) *.o test

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值