数据结构——链式队列

数据结构------链式队列

目录

一、概念

[1.1 结构组成](#1.1 结构组成)

二、基本操作

[2.1 结构体定义](#2.1 结构体定义)

[2.2 初始化](#2.2 初始化)

[2.3 入队](#2.3 入队)

[2.4 出队](#2.4 出队)

[2.5 获取队头元素值](#2.5 获取队头元素值)

[2.6 查找](#2.6 查找)

[2.7 判空](#2.7 判空)

[2.8 获取有效值个数](#2.8 获取有效值个数)

[2.9 清空](#2.9 清空)

[2.10 销毁](#2.10 销毁)

[2.11 打印](#2.11 打印)

[2.12 主函数测试](#2.12 主函数测试)

[三 总代码](#三 总代码)

.cpp代码

.h代码


一、概念

链式队列,通常也被称为链表队列或者简单链表,是一种使用链表实现的队列数据结构。队列是一种先进先出(FIFO)的数据结构,即最先添加到队列中的元素将是最先被移除的元素。链式队列通过链接一系列节点来实现队列的功能,每个节点包含数据部分和指向下一个节点的指针。

1.1 结构组成

链式队列通常由两个主要部分组成:

  1. 节点(Node):链式队列中的每个元素都是一个节点,包含两个主要部分:

    • 数据域(Data Field):用于存储队列中的实际数据。

    • 指针域(Pointer Field):通常是一个指针,指向链表中的下一个节点。

  2. 头尾指针:链式队列使用两个指针来分别指向队列的头部(front)和尾部(rear):

    • 头指针(Front):指向队列中的第一个节点,即最先进入队列的元素。

    • 尾指针(Rear):指向队列中的最后一个节点,即最后进入队列的元素。

二、基本操作

2.1 结构体定义

复制代码
typedef int ELEM_TYPE;

//链式队列有效结点结构体设计
typedef struct LQ_Node
{
	ELEM_TYPE data;//数据域
	struct LQ_Node* next;//指针域
}LQ_Node;


//链式队列的辅助结点结构体设计
typedef struct
{
	struct LQ_Node* front;//对头指针
	LQ_Node* rear;//队尾指针
}List_Queue;

2.2 初始化

复制代码
void Init_List_Queue(List_Queue* plq)
{
    assert(plq != NULL);

    plq->front = plq->rear = NULL;
}

2.3 入队

复制代码
bool Push(List_Queue* plq, ELEM_TYPE val)
{
    //0.assert
    assert(plq != NULL);

    //1.购买新节点
    struct LQ_Node* pnewnode = (LQ_Node*)malloc(sizeof(LQ_Node));
    if (pnewnode == NULL)
    {
        return false;
    }
    pnewnode->data = val;

    //2.分情况,看链式队列空不空
    //3.1.空,则修改对应3个指针
    if (IsEmpty(plq))
    {
        pnewnode->next = NULL;//3
        plq->front = plq->rear = pnewnode;//12
        return true;
    }
    //3.2.不空,则修改对应3个指针
    else
    {
        pnewnode->next = plq->rear->next;//3
        plq->rear->next = pnewnode;//1
        plq->rear = pnewnode;
        return true;
    }
}

2.4 出队

复制代码
bool Pop(List_Queue* plq)
{
    //0.assert 
    assert(plq != NULL);

    //1.确保有节点
    if (IsEmpty(plq))
        return false;

    //2.分情况处理(看此时的有效元素个数是=1还是大于1)
    //2.1 若当前仅有唯一一个有效元素
    struct LQ_Node* q = plq->front;

    if (q->next == NULL)
    {
        plq->front = plq->rear = NULL;
        free(q);
        q = NULL;
        return true;
    }
    //2.2 若当前有多个有效元素
    else
    {
        plq->front = q->next;
        free(q);
        q = NULL;
        return true;
    }
}

首先获取队头指针plq->front并赋值给q。当q->nextNULL时,说明队列中只有一个元素。此时将队列的头指针plq->front和尾指针plq->rear都设为NULL,然后释放该节点的内存,并将q设为NULL,最后返回true表示出队操作成功。

当队列中有多个元素时,将队列的头指针plq->front更新为原队头节点的下一个节点(即q->next),然后释放原队头节点的内存,并将q设为NULL,返回true表示出队操作成功。

2.5 获取队头元素值

复制代码
ELEM_TYPE Front(List_Queue* plq)
{
    //0.
    assert(plq != NULL);

    //1.
    if (IsEmpty(plq))
    {
        exit(1);
    }

    return plq->front->data;
}

2.6 查找

复制代码
LQ_Node* Search(List_Queue* plq, ELEM_TYPE val)
{
    //0.
    assert(plq != NULL);

    LQ_Node* p = plq->front;
    for (; p != NULL; p = p->next)
    {
        if (p->data == val)
            return p;
    }

    return NULL;
}

2.7 判空

复制代码
bool IsEmpty(List_Queue* plq)
{
    return plq->front == NULL;
    //return plq->rear == NULL;

}

2.8 获取有效值个数

复制代码
int Get_Size(List_Queue* plq)
{
    assert(plq != NULL);

    int count = 0;

    LQ_Node* p = plq->front;
    for (; p != NULL; p = p->next)
    {
        count++;
    }

    return count;
}

2.9 清空

复制代码
void Clear(List_Queue* plq)
{
    Destroy(plq);
}

2.10 销毁

复制代码
void Destroy(List_Queue* plq)
{
    //assert

    LQ_Node* p = plq->front;
    LQ_Node* q = NULL;

    while (p != NULL)
    {
        q = p->next;
        free(p);
        p = q;
    }

    plq->front = plq->rear = NULL;
}

2.11 打印

复制代码
void Show(List_Queue* plq)
{
    assert(plq != NULL);

    LQ_Node* p = plq->front;
    for (; p != NULL; p = p->next)
    {
        printf("%d ", p->data);
    }

    printf("\n");
}

2.12 主函数测试

复制代码
int main()
{
    srand((unsigned int)time(NULL));
    int tmp = rand() % 30;
    printf("%d\n", tmp);

    List_Queue head;
    Init_List_Queue(&head);

    Push(&head, 1);
    Push(&head, 2);
    Push(&head, 3);

    printf("Front = %d\n", Front(&head));
    Show(&head);

    Pop(&head);
    printf("Front = %d\n", Front(&head));
    Show(&head);


    Destroy(&head);
    Show(&head);
    return 0;
}

三 总代码

.cpp代码

复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <time.h>
#include "list_queue.h"


//可实现的函数操作:
//1.初始化
void Init_List_Queue(List_Queue* plq)
{
    assert(plq != NULL);

    plq->front = plq->rear = NULL;
}

//2.入队
bool Push(List_Queue* plq, ELEM_TYPE val)
{
    //0.assert
    assert(plq != NULL);

    //1.购买新节点
    struct LQ_Node* pnewnode = (LQ_Node*)malloc(sizeof(LQ_Node));
    if (pnewnode == NULL)
    {
        return false;
    }
    pnewnode->data = val;

    //2.分情况,看链式队列空不空
    //3.1.空,则修改对应3个指针
    if (IsEmpty(plq))
    {
        pnewnode->next = NULL;//3
        plq->front = plq->rear = pnewnode;//12
        return true;
    }
    //3.2.不空,则修改对应3个指针
    else
    {
        pnewnode->next = plq->rear->next;//3
        plq->rear->next = pnewnode;//1
        plq->rear = pnewnode;
        return true;
    }
}

//3.出队
bool Pop(List_Queue* plq)
{
    //0.assert 
    assert(plq != NULL);

    //1.确保有节点
    if (IsEmpty(plq))
        return false;

    //2.分情况处理(看此时的有效元素个数是=1还是大于1)
    //2.1 若当前仅有唯一一个有效元素
    struct LQ_Node* q = plq->front;

    //if (plq->rear == plq->front)
    if (q->next == NULL)
    {
        plq->front = plq->rear = NULL;
        free(q);
        q = NULL;
        return true;
    }
    //2.2 若当前有多个有效元素
    else
    {
        plq->front = q->next;
        free(q);
        q = NULL;
        return true;
    }
}

//4.获取队头元素值
ELEM_TYPE Front(List_Queue* plq)
{
    //0.
    assert(plq != NULL);

    //1.
    if (IsEmpty(plq))
    {
        exit(1);
    }

    return plq->front->data;
}

//4.5查找
LQ_Node* Search(List_Queue* plq, ELEM_TYPE val)
{
    //0.
    assert(plq != NULL);

    LQ_Node* p = plq->front;
    for (; p != NULL; p = p->next)
    {
        if (p->data == val)
            return p;
    }

    return NULL;
}

//5.判空
bool IsEmpty(List_Queue* plq)
{
    return plq->front == NULL;
    //return plq->rear == NULL;

}

//7.获取有效值个数 Size
int Get_Size(List_Queue* plq)
{
    assert(plq != NULL);

    int count = 0;

    LQ_Node* p = plq->front;
    for (; p != NULL; p = p->next)
    {
        count++;
    }

    return count;
}

//8.清空
void Clear(List_Queue* plq)
{
    Destroy(plq);
}

//9.销毁
void Destroy(List_Queue* plq)
{
    //assert

    LQ_Node* p = plq->front;
    LQ_Node* q = NULL;

    while (p != NULL)
    {
        q = p->next;
        free(p);
        p = q;
    }

    plq->front = plq->rear = NULL;
}

//10.打印
void Show(List_Queue* plq)
{
    assert(plq != NULL);

    LQ_Node* p = plq->front;
    for (; p != NULL; p = p->next)
    {
        printf("%d ", p->data);
    }

    printf("\n");
}


int main()
{
    srand((unsigned int)time(NULL));
    int tmp = rand() % 30;
    printf("%d\n", tmp);

    List_Queue head;
    Init_List_Queue(&head);

    Push(&head, 1);
    Push(&head, 2);
    Push(&head, 3);

    printf("Front = %d\n", Front(&head));
    Show(&head);

    Pop(&head);
    printf("Front = %d\n", Front(&head));
    Show(&head);


    Destroy(&head);
    Show(&head);
    return 0;
}

.h代码

复制代码
#pragma once
typedef int ELEM_TYPE;

//链式队列有效结点结构体设计
typedef struct LQ_Node
{
	ELEM_TYPE data;//数据域
	struct LQ_Node* next;//指针域
}LQ_Node;


//链式队列的辅助结点结构体设计
typedef struct
{
	struct LQ_Node* front;//对头指针
	LQ_Node* rear;//队尾指针
}List_Queue;

//可实现的函数
//1.初始化
void Init_List_Queue(List_Queue* plq);

//2.入队
bool Push(List_Queue* plq, ELEM_TYPE val);

//3.出队
bool Pop(List_Queue* plq);

//4.获取队头元素值
ELEM_TYPE Front(List_Queue* plq);

//4.5查找
LQ_Node* Search(List_Queue* plq, ELEM_TYPE val);

//5.判空
bool IsEmpty(List_Queue* plq);

//7.获取有效值个数 Size
int Get_Size(List_Queue* plq);

//8.清空
void Clear(List_Queue* plq);

//9.销毁
void Destroy(List_Queue* plq);

//10.打印
void Show(List_Queue* plq);
相关推荐
大小胖虎2 小时前
数据结构——第六章:图
数据结构·笔记··最小生成树·拓扑排序·最短路径
_GR7 小时前
2021年蓝桥杯第十二届C&C++大学B组真题及代码
c语言·数据结构·c++·算法·蓝桥杯
lwewan7 小时前
26考研——图_图的基本概念(6)
数据结构·考研
1haooo9 小时前
API-Arrays
java·数据结构·算法
无职转生真好看10 小时前
vector和list区别
数据结构·c++·list
deming_su12 小时前
第七课:Python基础排序算法与比较排序原理深度解析
数据结构·算法·排序算法
Phoebe鑫12 小时前
数据结构每日一题day1
数据结构
green5+112 小时前
LeetCode206反转链表
数据结构·链表
刃神太酷啦13 小时前
基础算法篇(2)(蓝桥杯常考点)
数据结构·c++·算法·蓝桥杯·深度优先·蓝桥杯c++组