首页 > 其他分享 >双向循环链表队列的接口设计

双向循环链表队列的接口设计

时间:2024-04-26 19:23:16浏览次数:26  
标签:Head 队列 接口 next 链表 Phead LkQueue New

/********************************************************************************************************
 *
 *
 * 该程序实现循环队列元素的增删改查,目的是提高设计程序的逻辑思维,另外为了提高可移植性,所以循环队列中元素
 * 的数据类型为DataType_t,用户可以根据实际情况修改循环队列中元素的类型。
 *
 * 另外,为了方便管理循环队列,所以用户设计SeqList_t结构体,该结构体中包含三个成员:地址+容量+有效元素的下标
 *
 *
 *
 * Copyright (c)  2023-2024   [email protected]   All right Reserved
 * ******************************************************************************************************/
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

// 指的是循环队列中的元素的数据类型,用户可以根据需要进行修改
typedef int DataType_t;

// 构造记录循环队列LinkQueue各项参数(循环队列的首地址 + 循环队列的容量 + 循环队列队尾下标+队首下标)的结构体
typedef struct LinkQueue
{
    DataType_t *data;       // 记录循环队列首地址
    struct LinkQueue *prev; // 循环队列节点的直接前驱
    struct LinkQueue *next; // 循环队列节点的直接后继

} LkQueue_t;

// 创建循环队列并对循环队列进行初始化
LkQueue_t *LkQueue_Create(void)
{
    // 1.利用calloc为循环队列的管理结构体申请一块堆内存
    LkQueue_t *Head = (LkQueue_t *)calloc(1, sizeof(LkQueue_t));

    if (NULL == Head)
    {
        perror("calloc memory for Head is failed");
        exit(-1); // 程序异常终止
    }

    // 3.对管理循环队列的结构体进行初始化
    Head->data = NULL; // 头节点不存数据
    Head->prev = Head; // 前驱和后继指向自己体现循环
    Head->next = Head;

    return Head;
}

// 创建一个新的链式队列节点
LkQueue_t *LkQueue_NewNode(DataType_t data)
{
    // 1.创建一个新结点并对新结点申请内存
    LkQueue_t *New = (LkQueue_t *)calloc(1, sizeof(LkQueue_t));
    if (NULL == New)
    {
        perror("Calloc memory for NewNode is Failed");
        return NULL;
    }

    // 2.对新结点的数据域和指针域进行初始化
    New->data = data;
    New->next = New;// 前驱和后继指向自己体现循环
    New->prev = New;

    return New;
}

// 判断循环队列是否为空
bool LkQueue_IsEmpty(LkQueue_t *Head)
{
    return (Head->next == Head) ? true : false;
}

// 入队
bool LkQueue_Enqueue(LkQueue_t *Head, DataType_t data)
{
    LkQueue_t *Phead = Head->next;
    LkQueue_t *New = LkQueue_NewNode(data);

    // 1.判断链表是否为空
    if (LkQueue_IsEmpty(Head))
    {
        Head->next = New;
    }
    else // 尾插入队
    {
        New->next = Phead;
        New->prev = Phead->prev;

        Phead->prev->next = New;
        Phead->prev = New;
    }

    return true;
}

// 出队
DataType_t LkQueue_Dequeue(LkQueue_t *Head)
{
    DataType_t temp = 0;
    LkQueue_t *Phead = Head->next;
    // 1.判断循环队列是否为空
    if (LkQueue_IsEmpty(Head))
    {
        printf("LkQueue is Empty!\n");
        return false;
    }
    // 2.判断是否只有首节点一个元素
    if (Phead->next == Phead)
    {
        Head->next = Head;
    }
    else
    {
        // 4.对头节点进行取值删除操作

        Phead->prev->next = Phead->next;
        Phead->next->prev = Phead->prev;
        Head->next = Phead->next;
    }

    temp = Phead->data;

    Phead->prev = NULL;
    Phead->next = NULL;
    free(Phead);

    return temp;
}

// 遍历顺序表的元素
void LkQueue_Print(LkQueue_t *Head)
{
    LkQueue_t *Phead = Head->next;
	
    while (Phead->next != Head->next)
    {
        printf("data=%d\n", Phead->data);
        Phead = Phead->next;
    }
    printf("data=%d\n", Phead->data);
}

int main(int argc, char const *argv[])
{

    // 1.创建双向循环链表队列
    LkQueue_t *Head = LkQueue_Create();

    // 2.向队列中插入新元素
    printf("*********************************入栈********************************\n");
    LkQueue_Enqueue(Head, 5);
    LkQueue_Enqueue(Head, 2);
    LkQueue_Enqueue(Head, 1);
    LkQueue_Enqueue(Head, 4);
    LkQueue_Enqueue(Head, 6);

    // //3.遍历队列
    LkQueue_Print(Head); // -- 5 2 1 4 6
    printf("\n");
    // 4.将已有队列中的内容输出
    printf("*********************************出栈********************************\n");
    printf("出队元素为%d\n", LkQueue_Dequeue(Head));
    printf("出队元素为%d\n", LkQueue_Dequeue(Head));
    printf("出队元素为%d\n", LkQueue_Dequeue(Head));
    printf("出队元素为%d\n", LkQueue_Dequeue(Head));
    printf("出队元素为%d\n", LkQueue_Dequeue(Head));

    // //5.遍历队列
    LkQueue_Print(Head); // --空
    printf("\n");

    // 2.向队列中插入新元素
    printf("*********************************入栈********************************\n");
    LkQueue_Enqueue(Head, 6);
    LkQueue_Enqueue(Head, 4);
    LkQueue_Enqueue(Head, 1);
    LkQueue_Enqueue(Head, 2);
    LkQueue_Enqueue(Head, 5);

    // //3.遍历队列
    LkQueue_Print(Head); // -- 6 4 1 2 5
    printf("\n");
    return 0;
}

标签:Head,队列,接口,next,链表,Phead,LkQueue,New
From: https://www.cnblogs.com/eon4051/p/18160723

相关文章

  • 环形队列
    【简介】ringbuffer/circularbuffer又名环形队列/环形缓冲区,其通过开辟固定尺寸的内存来实现反复复用同一块内存的目的。由于预先开辟了固定尺寸的内容,所以当数据满的时候,可以有两种处理方式,具体使用哪一种按照实际需求,具体如下:1)当队列满的时候,新来的数据会覆盖最古老的......
  • 循环队列的程序接口
    循环队列的程序接口目录循环队列的程序接口队列的说明队列循环队列入队、出队头文件创建队空、队满的判断入队出队验证队列的说明队列循环队列入队、出队头文件/********************************************************************* filename: 循环队列的接口......
  • spring-接口大全
    1.Bean相关1.InitializingBeanInitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。demo@ComponentpublicclassMyInitBeanimplementsInitializingBean{publicvoidafterPro......
  • TODO-力扣-707. 设计链表
    1.题目题目地址(707.设计链表-力扣(LeetCode))https://leetcode.cn/problems/design-linked-list/题目描述你可以选择使用单链表或者双链表,设计并实现自己的链表。单链表中的节点应该具备两个属性:val和next。val是当前节点的值,next是指向下一个节点的指针/引用。如果......
  • PHP身份实名认证接口小白也能轻松实现,ocr接口
    还在为网站用户的身份验证头疼不已?不要慌,今天就带你揭秘如何用PHP语言快速搭建起安全可靠的身份实名认证接口系统!只需对接身份证实名认证接口即可轻松实现用户身份的实名认证。那么,如何用PHP语言实现呢?其实很简单,登录翔云,找到开发者中心,下载所需要的接口开发语言,只需更......
  • 基于禅道restful接口的二次开发-获取token
    使用禅道的时候,可能会想用禅道的接口来做一些二次开发,比如获取缺陷情况、案例执行情况,做一些统计报表的展示。根据禅道开发文档中相关说明,在禅道开源版16.0+,专业版11.0+,企业版6.0+,旗舰版2.4+新增RESTful风格API,因此可以利用api来获取相关的数据访问地址:http://****/zentao/a......
  • qt封装dll并静态调用其它接口
    开发套件为QT5.9+MinGW编译器首先创建dll,第一步创建一个打开pro文件,因为我们创建的是app,需要的是dll,修改app->lib,注意不是dll其次,静态调用自己的底层库在工程中加入头文件,在pro添加dll的路径(注意这里静态调用没有用到lib文件)添加示例接口将编译的dll放入测试环境......
  • 单调队列优化DP
    单调队列优化dp单调队列可以求某固定区间的最值,所以dp中需要求某固定区间的最值则可以考虑使用单调队列优化单调队列-滑动窗口https://www.luogu.com.cn/problem/P1886/**@Author:Danc1ng*@Date:2024-04-2416:06:34*@FilePath:P1886滑动窗口[模......
  • 链栈的接口程序
    /***************************************************filename:LkStack.c*author:[email protected]*date:2024/04/25*brief:构建链栈*note:None**CopyRight(c)[email protected]********......
  • 双向循环链表的删除、插入
    双向循环链表双向循环链表是一种特殊的链表结构,它结合了双向链表和循环链表的特点。在双向循环链表中,每个节点都有两个指针,一个指向前一个节点,另一个指向后一个节点,从而形成双向链接。同时,链表的头节点和尾节点相互链接,形成一个循环结构。这种结构使得双向循环链表在遍历和操作......