数据结构-链式队列

逻辑结构:线性结构

存储结构:链式存储

1.结构体

typedef int datatype;
typedef struct node
{
    datatype data;     // 数据域
    struct node *next; // 指针域
} linkqueue_node_t, *linkqueue_list_t;

// linkqueue_list_t p === linkqueue_node_t *

typedef struct // 将队列头指针和尾指针封装到一个结构体里
{
    linkqueue_list_t front; // 相当于队列的头指针
    linkqueue_list_t rear;  // 相当于队列的尾指针
    // 有了链表的头指针和尾指针,那么我们就可以操作这个链表
} linkqueue_t;

2.创建空队列

(1)开辟一个结构体类型大小的空间作为头结点

(2)开辟一块指针类型大小的空间存放头尾指针

(3)初始化头节点为空,初始化头尾指针指向头节点。

// 1.创建一个空的队列,用有头链表
linkqueue_t *CreateEmptyLinkQueue()
{
    // 创建头节点
    linkqueue_node_t *head = malloc(sizeof(linkqueue_node_t));
    if (head == NULL)
    {
        perror("head malloc error");
        return NULL;
    }
    // 头节点初始化
    head->next = NULL;

    // 创建空间存放头尾指针
    linkqueue_t *p = (linkqueue_t *)malloc(sizeof(linkqueue_t));

    if (p == NULL)
    {
        perror("q malloc error");
        return NULL;
    }
    // 初始化头尾指针,头尾指针指向头节点
    p->front = head;
    p->rear = head;

    return p;
}

3.入列

步骤:

(1)新建节点存放数据,指针域置空

(2)将新节点尾插到链表后

(3)移动尾节点,让新建节点成为新的尾节点

// 2.入列 data代表入列的数据
int InLinkQueue(linkqueue_t *p, datatype data)
{
    // 创建新节点
    linkqueue_node_t *pnew = (linkqueue_node_t *)malloc(sizeof(linkqueue_node_t));
    // 初始化新节点
    pnew->data = data;
    pnew->next = NULL;

    // 连接新节点到链表
    p->rear->next = pnew;
    // 移动尾指针
    p->rear = pnew;

    return 0;
}

4.出列

释放头节点,将头节点的下一个节点做成新的头节点通过返回其数据域中数据(相当于数据域无效了成为头节点了)。

步骤:

(1)判断队列是否为空

(2)用指针指向要释放头节点,暂存头节点

(3)头指针后移,第二个节点作为新的头节点

(4)释放旧的头节点

(5)返回要出队的数据,也就是现在新的头节点的数据

// 3.出列
datatype OutLinkQueue(linkqueue_t *p)
{
    datatype temp;
    // 判空
    if (IsEmptyLinkQueue(p))
    {
        perror("队列已空");
        return -1;
    }

    // 创建指针指向将要出队的头节点
    linkqueue_node_t *pdel;
    pdel = p->front;

    // 数据出队
    temp = pdel->next->data;
    // 等同于 temp = p->front->next->data;

    // 移动头节点
    p->front = p->front->next;

    // 释放空间
    free(pdel);
    pdel = NULL;

    printf("%d\n", temp);

    return temp;
}

// 4.判断队列是否为空
int IsEmptyLinkQueue(linkqueue_t *p)
{
    return p->front == p->rear;
}

 5.计算队列长度

定义一个指针循环遍历队列的节点,每遍历到一个节点,长度+1

// 5.求队列长度的函数
int LengthLinkQueue(linkqueue_t *p)
{
    int length = 0;
    // 定义结构体类型的指针代替头指针移动
    linkqueue_node_t *p1;
    p1 = p->front;

    while (p1 != p->rear)
    {
        p1 = p1->next;
        length++;
    }

    printf("长度为:%d\n", length);
    return length;
}

6.清空队列

与出队比较相似,不断后移头指针,不断释放头节点。

// 6.清空队列
int ClearLinkQueue(linkqueue_t *p)
{
    // 循环释放头节点
    // 创建指针指向出队的节点
    linkqueue_node_t *pdel = NULL;

    while (p->front != p->rear)
    {
        // 指向释放的头节点
        pdel = p->front;

        // 移动头指针,让第二个节点成为新的头节点
        p->front = p->front->next;

        // 释放头节点
        free(pdel);
        pdel = NULL;
    }

    // 判空
    if (IsEmptyLinkQueue(p))
    {
        perror("队列已空");
        return 0;
    }

    return 0;
}

7.头文件

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

typedef int datatype;
typedef struct node
{
    datatype data;     // 数据域
    struct node *next; // 指针域
} linkqueue_node_t, *linkqueue_list_t;

// linkqueue_list_t p === linkqueue_node_t *

typedef struct // 将队列头指针和尾指针封装到一个结构体里
{
    linkqueue_list_t front; // 相当于队列的头指针
    linkqueue_list_t rear;  // 相当于队列的尾指针
    // 有了链表的头指针和尾指针,那么我们就可以操作这个链表
} linkqueue_t;

// 1.创建一个空的队列
linkqueue_t *CreateEmptyLinkQueue();

// 2.入列 data代表入列的数据
int InLinkQueue(linkqueue_t *p, datatype data);

// 3.出列
datatype OutLinkQueue(linkqueue_t *p);

// 4.判断队列是否为空
int IsEmptyLinkQueue(linkqueue_t *p);

// 5.求队列长度的函数
int LengthLinkQueue(linkqueue_t *p);

// 6.清空队列
int ClearLinkQueue(linkqueue_t *p);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值