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

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

时间:2024-04-28 23:34:14浏览次数:27  
标签:Head 队列 LinkQueue 结点 接口 Next 链表 NewNode Prev

/*************************************************
 *
 *   file name:DoubleLinkQueue.c
 *   author   :[email protected]
 *   date     :2024/04/28
 *   brief    :构建双向循环链队的接口
 *   note     :None
 *
 *   CopyRight (c) 2024    [email protected]    All Right Reseverd
 *
 **************************************************/
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
/*************************************************
 *
 *   func name     :
 *   brief         :
 *   func parameter:
 *
 *
 *   return        :None
 *   note          :None
 *   func author   :[email protected]
 *   date          :2024/04/28
 *   version       :V1.0
 **************************************************/
// 构建链队的结点(队数据域+指针域1+指针域2)
typedef int DataType_t;
typedef struct LinkQueue
{
    DataType_t Data;
    struct LinkQueue *Prev;
    struct LinkQueue *Next;

} LinkQueue_t;

// 创建一个空的顺序循环队列,并对其进行初始化
LinkQueue_t *LinkQueue_Creat(void)
{
    // 为循环队列的头结点申请内存空间
    LinkQueue_t *Head = (LinkQueue_t *)calloc(1, sizeof(LinkQueue_t));
    if (NULL == Head)
    {
        perror("calloc memory for Head is failed!\n");
        exit(-1);
    }
    Head->Next = Head;
    Head->Prev = Head;
    return Head;
}
// 创建新结点,并对其进行初始化
LinkQueue_t *LinkQueue_NewNode(DataType_t data)
{
    // 为循环队列的头结点申请内存空间
    LinkQueue_t *NewNode = (LinkQueue_t *)calloc(1, sizeof(DataType_t));
    if (NULL == NewNode)
    {
        perror("calloc memory for NewNode is failed!\n");
        return NewNode;
    }
    NewNode->Data = data;    // 初始化数据域
    NewNode->Prev = NewNode; // 初始化指针域1
    NewNode->Next = NewNode; // 初始化指针域2
    return NewNode;
}

// 判断队列是否为空
bool LinkQueue_IsEmpty(LinkQueue_t *Head)
{
    return (Head->Next == Head) ? true : false;
}

// 入队操作(尾插)
bool LinkQueue_Enqueue(LinkQueue_t *Head, DataType_t data)
{
    LinkQueue_t *Phead = Head->Next;
    LinkQueue_t *NewNode = LinkQueue_NewNode(data);
    if (LinkQueue_IsEmpty(Head)) // 判断链表是否为空
    {
        // 链表为空
        Head->Next = NewNode;    // 让头结点的Next指针指向新结点
        NewNode->Next = NewNode; // 让新结点的Next指针指向新结点
        NewNode->Prev = NewNode; // 让新结点的Prev指针指向新结点
        return true;
    }

    // 2.2链表非空

    NewNode->Prev = Phead->Prev; // 新节点的Prev指针指向尾结点
    NewNode->Next = Phead;       // 新结点的Next指针指向首结点
    Phead->Prev->Next = NewNode; // 尾结点的Next指针指向新结点
    Phead->Prev = NewNode;       // 首结点的Prev指针指向新结点
    return true;
}

// 出队操作(头删)
DataType_t LinkQueue_Dequeue(LinkQueue_t *Head)
{
    // 判断链表是否为空
    if (LinkQueue_IsEmpty(Head))
    {
        printf("Link queue is empty!\n");
        return false; // 为空则删除失败
    }
    DataType_t temp = Head->Next->Data;
    LinkQueue_t *Phead = Head->Next; // 备份首节点地址,用于最后释放首结点地址
    Phead->Prev->Next = Phead->Next; // 让尾结点的Next指针指向首节点的直接后继结点
    Phead->Next->Prev = Phead->Prev; // 让首结点的直接后继结点的Prev指针指向尾结点
    Head->Next = Phead->Next;        // 让头结点的Next指针指向首结点的直接后继结点
    Phead->Next = NULL;              // 让首结点的Next指针指向NULL
    Phead->Prev = NULL;              // 让首结点的Prev指针指向NULL
    free(Phead);
    return temp;
}

bool LinkQueue_Print(LinkQueue_t *Head)

{
    LinkQueue_t *Front = Head->Next; // 备份头结点

    while (Front->Next != Head->Next)
    {
        printf("%d ", Front->Data); // 打印链表

        Front = Front->Next; // 遍历链表
    }

    printf("%d ", Front->Data);
    printf("\n");
    return true;
}
int main(void)
{
    LinkQueue_t *Head = LinkQueue_Creat();
    LinkQueue_Enqueue(Head, 1);
    LinkQueue_Enqueue(Head, 2);
    LinkQueue_Enqueue(Head, 3);

    LinkQueue_Print(Head);
    printf("The dequeue element is %d\n", LinkQueue_Dequeue(Head));
    LinkQueue_Print(Head);
    return 0;
}

标签:Head,队列,LinkQueue,结点,接口,Next,链表,NewNode,Prev
From: https://www.cnblogs.com/bell-c/p/18164756

相关文章

  • java学习-接口
    01、定义接口接口用interface关键字去表示,不可以带私有化修饰符,比如protected、final等。接口就是用来被继承implements实现的,如果不允许访问,那就没意义了。接口同样不允许new实例化。02.接口的作用第一,使某些实现类具有我们想要的功能,比如说,实现了Cloneable接口的类具有拷贝......
  • 接口测试学习111
    1、同步接口:2、异步接口:不需要等接口的调用结果也可以继续执行。轮询方式。3、回调接口:一、代理类型1、协议:http、https。代理fiddler2、协议:TCP协议簇,代理:socks43、协议:TCP、UDP协议簇,代理:socks5二、接口测试范围/类型1、接口功能测2、接口性能和安全测试3、接口兼容性......
  • 短信验证码登录接口,如何防止恶意攻击
    本文相关词汇:OTP-One-TimePassword一次性动态密码,这种验证码具有时效性,通常有效期在1~2分钟内。手机短信验证码就是一种OTP。MFA-多重因子认证。先说单因子认证,我们的系统登录通常是账密登录,这种就是单因子认证方式的登录。现在为了安全,许多网站开始使用双因子认证登录......
  • 接口规范
    需要注意兼容php、java等多语言,即弱类型+强类型如返回user_name字符串类型,就不能查询失败返回null 返回json格式codeint格式msgstring格式data根据接口不同返回不同格式一般是对象或者数组,如果不需要使用data,可以返回null(默认null) php创建对象$obj=newstdClas......
  • system消息队列和posix消息队列
    POSIX消息队列System消息队列主要函数头文件#include<sys/msg.h>intmsgget(key_tkey,intoflag)intmsgsnd(intmsqid,constvoid*ptr,size_tlength,intflag)ssize_tmsgrcv(intmsqid,void*ptr,size_tlength,longtype,intflag)intmsgctl(intmsqid,......
  • Python-PyQt5接口压测工具分享
    1、页面介绍  2、运行效果 ......
  • C#身份查验接口、身份证文字识别接口、金融身份验证
    针对金融领域远程自主开户的实名认证,翔云人工智能开放平台提出了有针对性的解决方案。翔云实名认证API其中包含了身份证实名认证、人脸识别、人证合一和银行卡实名认证,可快速识别提取用户身份信息,实时联网权威数据源进行用户身份的验证,既解决了远程身份认证问题,也避免了身份被......
  • .net core,.net 6使用SoapCore开发webservice接口,以及使用HttpClientFactory动态访问we
    1.使用soapCorenuget包 2.新建接口及实现2.1新建接口 2.2新建实现 2.3新建接收实体 2.4返回实体 3.接口注入使用  4.启动程序,直接访问对应的asmx地址  ......
  • 链表
    P1996约瑟夫问题动态链表临时分配链表节点,使用完毕后释放链表节点。优点:能及时释放空间,不使用多余内存缺点:需要管理空间,容易出错。#include<bits/stdc++.h>#defineintlonglong#definerep(i,a,b)for(inti=(a);i<=(b);++i)#definefep(i,a,b)for(int......
  • 如何写接口设计文档?
    小系统或单个模块的设计文档一、「一句话描述」的标题文件名或标题最好使用「一句话描述」,如:观测云新Event数据结构及处理逻辑设计观测云云关联处理逻辑设计二、业务流程对业务流程进行描述,具体写明「用户做了什么操作,系统进行了什么处理,最后发生了什么」。一般是流程图......