快速学会数据结构中的链式队列与循环队列

一、链式队列

**队列:**一种允许从一端插入数据,另外一端删除数据的线性存储结构称为队列。

把数据插入的这端称为队列的队尾, 数据删除这端称为队列的队头。

插入操作称为入队;删除操作称为出队。

特点: 先进先出、后进后出**(FIFO)**

应用: 数据缓存

链式队列:

基本操作程序代码:

cpp 复制代码
#include "linkqueue.h"
#include <stdio.h>
#include <stdlib.h>

LQue_t * create_link_queue()
{
    LQue_t *pque = malloc(sizeof(LQue_t)); 
    if (NULL == pque)
    {
        printf("malloc error\n");
        return NULL;
    }  
    pque->phead = NULL;
    pque->ptail = NULL;
    pque->clen = 0;

    return pque;
}

int is_empty_link_queue(LQue_t *pque)
{
    return NULL == pque->phead;
}
int push_link_queue(LQue_t *pque, Data_t data)
{
    Node_t *pnode = malloc(sizeof(Node_t));
    if (NULL == pnode)
    {
        printf("malloc error\n");
        return -1;
    }
    pnode->data = data;
    pnode->pnext = NULL;

    if (is_empty_link_queue(pque))
    {
        pque->phead = pnode;
        pque->ptail = pnode;
    }
    else
    {
        pque->ptail->pnext = pnode;
        pque->ptail = pnode;
    }
    pque->clen++;

    return 0;
}

void show_link_queue(LQue_t *pque)
{
    Node_t *ptmp = pque->phead;
    while (ptmp != NULL)
    {
        printf("%d ", ptmp->data);
        ptmp = ptmp->pnext;
    }
    printf("\n");
}


int pop_link_queue(LQue_t *pque, Data_t *pdata)
{
    if (is_empty_link_queue(pque))
    {
        return -1;
    }

    Node_t *pfree = pque->phead;
    pque->phead = pfree->pnext;
    if (pdata != NULL)
    {
        *pdata = pfree->data;
    }
    free(pfree);
    if (NULL == pque->phead)
    {
        pque->ptail = NULL;
    }
    pque->clen--;

    return 0;
}

int get_link_queue_head(LQue_t *pque, Data_t *pdata)
{
    if (is_empty_link_queue(pque))
    {
        return -1;
    }
    if (pdata != NULL)
    {
        *pdata = pque->phead->data;
        return 0;
    }

    return -1;
}

void destroy_link_queue(LQue_t *pque)
{
    while (!is_empty_link_queue(pque))
    {
        pop_link_queue(pque, NULL);
    }
    free(pque);
}

二、循环队列

**循环队列:**使用顺序结构存储队列数据时,为了避免假溢出,使得顺序队列成为一种尾首相接的存储方式。

假溢出: 如下图,普通的顺序队列存在假溢出问题,所以一般使用循环队列。

**循环队列判空:**head == tail

循环队列判满:(tail+1)%len == head

基本操作程序代码:

cpp 复制代码
#include "seqqueue.h"
#include <stdio.h>
#include <stdlib.h>

SQue_t *create_seq_queue()
{
    SQue_t *psq = malloc(sizeof(SQue_t));
    if (NULL == psq)
    {
        printf("malloc error\n");
        return NULL;
    }
    psq->pbase = malloc(SEQ_MAX_LEN*sizeof(Data_t));
    if (NULL == psq->pbase)
    {
        printf("malloc error\n");
        return NULL;
    }

    psq->head = 0;
    psq->tail = 0;

    return psq;
}

int is_full_seq_queue(SQue_t *psq)
{
    return (psq->tail+1)%SEQ_MAX_LEN == psq->head;
}

int is_empty_seq_queue(SQue_t *psq)
{
    return psq->head == psq->tail;
}
int push_seq_queue(SQue_t *psq, Data_t data)
{
    if (is_full_seq_queue(psq))
    {
        return -1;
    }

    psq->pbase[psq->tail] = data;
    psq->tail = (psq->tail+1) % SEQ_MAX_LEN;

    return 0;
}

void show_seq_queue(SQue_t *psq)
{
    int i = 0;
    for (i = psq->head; i != psq->tail; i = (i+1)%SEQ_MAX_LEN)
    {
        printf("%d ", psq->pbase[i]);
    }
    printf("\n");
}

int pop_seq_queue(SQue_t *psq, Data_t *pdata)
{
    if(is_empty_seq_queue(psq))
    {
        return -1;
    }

    if (pdata != NULL)
    {
        *pdata = psq->pbase[psq->head];
    }
    psq->head = (psq->head + 1)% SEQ_MAX_LEN;

    return 0;
}


int get_seq_queue_head(SQue_t *psq, Data_t *pdata)
{
    if (is_empty_seq_queue(psq))
    {
        return -1;
    }
    if (pdata != NULL)
    {
        *pdata = psq->pbase[psq->head];

        return 0;
    }

    return -1;
}


void destroy_seq_queue(SQue_t *psq)
{
    free(psq->pbase);
    free(psq);
}
相关推荐
niuTaylor几秒前
飞腾 FT-2000/4 Ubuntu 内存卡 / NVMe SSD 系统制作完整指南
linux·服务器·人工智能·驱动开发·单片机
mmmmath_314 分钟前
LeetCode.225.用队列实现栈
算法
Elaine33615 分钟前
数据结构与算法-程序
数据结构·python·算法·计算机基础·编程基础
2601_9657422218 分钟前
布局GEO AI本地营销,我重点看这几个细节
大数据·人工智能·算法·ai·新媒体运营
EatFan18 分钟前
AI Agent 上生产前先加三道闸门:审批、限权、可回放的工程实践
人工智能·python·算法·多智能体·ai agent·mcp·harness
思茂信息41 分钟前
CST软件BCI仿真模型及仿真案例
开发语言·单片机·嵌入式硬件·算法·emc
Persistent的粽子!1 小时前
双指针算法:最大盛水容器
c++·算法·leetcode
傲世仙尊1 小时前
信号量环形队列与线程池起步-把临界资源拆成很多份
linux
小小龙学IT1 小时前
三菱 PLC MC 协议(SLMP / QnA 兼容 3E 帧)深度解析:从帧结构到 C++/Go 双语言采集实战
c语言·c++·golang
Huangjin007_1 小时前
【Linux 系统篇(二十五)】文件(二) 系统文件I/O详解
linux·运维·服务器