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

设计双向链表的接口

时间:2024-04-24 21:23:47浏览次数:19  
标签:tmp head DoubleLList 接口 next 链表 双向 NULL

/**********************************************************************************
*

  •      file name:  004_双向链表.c
    
  •      author   :  [email protected]
    
  •      date     :  2024/04/24
    
  •      function :  设计双向循环链表的接口
    
  •      note     :  None
    
  •      CopyRight (c) 2024-2024  [email protected]    All Right Reseverd
    
  • *******************************************************************************/
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>


//指的是双向链表中的结点有效数据类型,用户可以根据需要进行修改
typedef int  DataType_t;

//构造双向链表的结点,链表中所有结点的数据类型应该是相同的
typedef struct DoubleLinkedList
{
	DataType_t  		     data; //结点的数据域
	struct DoubleLinkedList	*prev; //直接前驱的指针域
	struct DoubleLinkedList	*next; //直接后继的指针域

}DoubleLList_t;
/* *********************************************************************************
 *
 *          
 *     @function name:	DoubleLList_Create
 *     @brief        :  创建一个空双向链表,空链表应该有一个头结点,对链表进行初始化
 *     @param        :  无
 *     @retval       :
 *              @head:  返回头节点
 *     @date         :  2024/04/24
 *     @version      : 1.0 
 *     @note         :  该函数定义头节点并初始化头节点,再返回头节点
 * 
 *
 *
 * *******************************************************************************/
DoubleLList_t * DoubleLList_Create(void)
{
	//1.创建一个头结点并对头结点申请内存
	DoubleLList_t *Head = (DoubleLList_t *)calloc(1,sizeof(DoubleLList_t));
	if (NULL == Head)
	{
		perror("Calloc memory for Head is Failed");
		exit(-1);
	}

	//2.对头结点进行初始化,头结点是不存储数据域,指针域指向NULL
	Head->prev = NULL;
	Head->next = NULL;

	//3.把头结点的地址返回即可
	return Head;
}
/* *********************************************************************************
 *
 *          
 *     @function name:	DoubleLList_NewNode
 *     @brief        :  创建新的结点,并对新结点进行初始化(数据域 + 指针域)
 *     @param        :  
 *                      @data:传将来的数据
 *     @retval       :
 *                      @New : 返回新数据的节点
 *     @date         : 2024/04/24
 *     @version      :1.0 
 *     @note         : 该函数将传进来的数据创建新节点并初始化,返回新节点
 * 
 *
 * *******************************************************************************/
//创建新的结点,并对新结点进行初始化(数据域 + 指针域)
DoubleLList_t * DoubleLList_NewNode(DataType_t data)
{
	//1.创建一个新结点并对新结点申请内存
	DoubleLList_t *New = (DoubleLList_t *)calloc(1,sizeof(DoubleLList_t));
	if (NULL == New)
	{
		perror("Calloc memory for NewNode is Failed");
		return NULL;
	}

	//2.对新结点的数据域和指针域(2个)进行初始化
	New->data = data;
	New->prev = NULL;
	New->next = NULL;

	return New;
}```

/* *********************************************************************************
*
*

  • @function name:	DoubleHeadInsert
    
  • @brief        :  将数据插入链表的头部
    
  • @param        :  
    
  •                  @data:传将来的数据
    
  •                  @head:头节点
    
  • @retval       :
    
  •                  @New:布尔类型的真或假
    
  • @date         : 2024/04/24
    
  • @version      :1.0 
    
  • @note         : 无
    
  • *******************************************************************************/```
//头插
bool DoubleHeadInsert(DoubleLList_t *head,DataType_t data)
{
    DoubleLList_t * New = DoubleLList_NewNode(data);
    //1.判断是否为空链表
    if (head->next == NULL)
    {
        
        head->next = New;
        return true;
    }
    //不为空直接插入
    New->next = head->next;
    head->next->prev = New;
    head->next = New;
    return true;
}```

/* *********************************************************************************
*
*

  • @function name:	DoubleTailInsert
    
  • @brief        :  将数据插入链表的尾部
    
  • @param        :  
    
  •                  @data:传将来的数据
    
  •                  @head:头节点
    
  • @retval       :
    
  •                  @New:布尔类型的真或假
    
  • @date         : 2024/04/24
    
  • @version      :1.0 
    
  • @note         : 无
    
  • *******************************************************************************/```
//尾插
bool DoubleTailInsert(DoubleLList_t *head,DataType_t data)
{
    DoubleLList_t * New = DoubleLList_NewNode(data);
    //1.判断是否为空链表
    if (head->next == NULL)
    {
        
        head->next = New;
        return true;
    }
    DoubleLList_t *tmp = head;
    //遍历
    while (tmp->next)
    {
        tmp = tmp->next;
    }
    New->prev = tmp;
    tmp->next = New;
    return true;

}```

/* *********************************************************************************
*
*

  • @function name:	DoubleDesInsert
    
  • @brief        :  将数据插入链表指定数据后的位置
    
  • @param        :  
    
  •                  @data   :传将来的数据
    
  •                  @destval:指定数据
    
  •                  @head   :头节点
    
  • @retval       :
    
  • @date         : 2024/04/24
    
  • @version      :1.0 
    
  • @note         : 该函数是将数据插入指定数据的直接后继节点
    
  • *******************************************************************************/```
//指定插
void DoubleDesInsert(DoubleLList_t *head,DataType_t destval,DataType_t data)
{
    DoubleLList_t * New = DoubleLList_NewNode(data);
    //1.判断是否为空链表
    if (head->next == NULL)
    {
        head->next = New;
        return;
    }
    DoubleLList_t *tmp = head;
    //遍历
    while (tmp->data != destval)
    {
        tmp = tmp->next;
        //插在尾部
        if (tmp->next == NULL)
        {
            New->prev = tmp;
            tmp->next = New;
            return;
        }
        
    }
    New->next = tmp->next;
    New->prev = tmp;
    tmp->next->prev = New;
    tmp->next = New;
    return;
}
/* *********************************************************************************
 *
 *          
 *     @function name:	DoubleHeadDel
 *     @brief        :  将数据从头部删除
 *     @param        :  
 *                      @head   :头节点
 *     @retval       :
 *                      无
 *     @date         : 2024/04/24
 *     @version      :1.0 
 *     @note         : 无
 * 
 *
 * *******************************************************************************/

//头删
void DoubleHeadDel(DoubleLList_t *head)
{
    //1.判断是否为空链表
    if (head->next == NULL)
    {
        printf("该链表为空!没有数据可以删除\n");
        return;
    }
    //2.判断是否只有一个节点
    if (head->next->next == NULL)
    {
        head->next = NULL;
        free(head->next);
        return;
    }
    //3.有多个数据的头删
    DoubleLList_t *tmp = head->next;//临时节点备份首节点
    head->next = tmp->next;
    tmp->next->prev = NULL;
    tmp->next = NULL;
    free(tmp);
    return;
}
/* *********************************************************************************
 *
 *          
 *     @function name:	DoubleTailDel
 *     @brief        :  将数据从尾部删除
 *     @param        :  
 *                      @head   :头节点
 *     @retval       :
 *                      无
 *     @date         : 2024/04/24
 *     @version      :1.0 
 *     @note         : 无
 * 
 *
 * *******************************************************************************/

//尾删
void DoubleTailDel(DoubleLList_t *head)
{
    //1.判断是否为空链表
    if (head->next == NULL)
    {
        printf("该链表为空!没有数据可以删除\n");
        return;
    }
    //2.判断是否只有一个节点
    if (head->next->next == NULL)
    {
        head->next = NULL;
        free(head->next);
        return;
    }
    //3.多个数据尾删
    DoubleLList_t *tmp = head->next;//临时节点备份首节点
    while (tmp->next != NULL)
    {
        tmp = tmp->next;
    }
    tmp->prev->next = NULL;
    tmp->prev = NULL;
    free(tmp);
    return;
    
}```

/* *********************************************************************************
*
*

  • @function name:	DoubleDestDel
    
  • @brief        :  将数据从指定位置删除
    
  • @param        :  
    
  •                  @head   :头节点
    
  •                  @destval:指定的数据
    
  • @retval       :
    
  • @date         : 2024/04/24
    
  • @version      :1.0 
    
  • @note         : 该函数是将指定删除数据的节点删除,如果输入的节点数据在链表中没有,那么会出del error信息
    
  • *******************************************************************************/```
//指定删
void DoubleDestDel(DoubleLList_t *head,DataType_t destval)
{
    //1.判断是否为空链表
    if (head->next == NULL)
    {
        printf("该链表为空!没有数据可以删除\n");
        return;
    }
    //2.判断是否只有一个节点
    if (head->next->next == NULL&& head->next->data == destval)
    {
        head->next = NULL;
        free(head->next);
        return;
    }
    
    DoubleLList_t *tmp = head->next;//临时节点备份首节点
    //3.判断条件改成对比数据是否相等,不相等进去循环,往后遍历
    while (tmp->data != destval)
    {
        tmp = tmp->next;
        // 需要删除的节点刚好在尾节点
        if (tmp->next == NULL)
        {
            if (tmp->data == destval)
            {
                tmp->prev->next = NULL;
                tmp->prev = NULL;
                free(tmp);
            }
            else
            {
                printf("del error!\n");
            }
            return;
        }
    }
    // 想要删除的节点刚好在首节点
    if (tmp->data == destval && tmp->prev == NULL)
    {
        head->next = tmp->next;
        tmp->next->prev = NULL;
        tmp->next = NULL;
        free(tmp);
        return;
    }
    tmp->prev->next = tmp->next;
    tmp->next->prev = tmp->prev;
    tmp->next = NULL;
    tmp->prev = NULL;
    free(tmp);
    return;
}```

/* *********************************************************************************
*
*

  • @function name:	DoubleLList_printf
    
  • @brief        :  将数据从链表中打印出来
    
  • @param        :  
    
  •                  @head   :头节点
    
  • @retval       :
    
  • @date         : 2024/04/24
    
  • @version      :1.0 
    
  • @note         : 无
    
  • *******************************************************************************/```
    //遍历链表
    void DoubleLList_printf(DoubleLList_t *head)
    {
    //判断是否为空链表
    if (head->next == NULL)
    {
    printf("The Link is empty!\n");
    return;
    }
    DoubleLList_t *tmp = head;
    while (tmp->next)
    {
    //把头结点的直接后继作为新的头结点
    tmp = tmp->next;

     //输出头结点的直接后继的数据域
     printf("data = %d\n",tmp->data);
    
     //判断是否到达尾结点,尾结点的next指针是指向首结点的地址
     if (tmp->next == NULL)
     	return;
    

    }

}

int main(int argc, char const *argv[])
{
	DoubleLList_t *head = DoubleLList_Create();

    DoubleHeadInsert(head,1);
    DoubleHeadInsert(head,2);
    DoubleHeadInsert(head,6);
    DoubleHeadInsert(head,7);
    DoubleHeadInsert(head,8);
    DoubleHeadInsert(head,9);
    DoubleHeadInsert(head,100);
    DoubleLList_printf(head);
    printf("\n");
    //尾插
    printf("尾插法:\n");
    DoubleTailInsert(head,10);
    DoubleLList_printf(head);

    printf("\n");
    //指定插
    printf("指定插法:\n");
    DoubleDesInsert(head,10,5);
    DoubleDesInsert(head,1,50);
    DoubleLList_printf(head);

    printf("\n");
    //头删
    printf("头删法:\n");
    DoubleHeadDel(head);
    DoubleLList_printf(head);

    printf("\n");
    //尾删
    printf("尾删法:\n");
    DoubleTailDel(head);
    DoubleLList_printf(head);

    printf("\n");
    //指定删
    printf("指定删法:\n");
    DoubleDestDel(head,9);
    DoubleDestDel(head,6);
    DoubleDestDel(head,10);
    DoubleDestDel(head,55);
    DoubleLList_printf(head);
	return 0;
}```

标签:tmp,head,DoubleLList,接口,next,链表,双向,NULL
From: https://www.cnblogs.com/wwwwariana/p/18156376

相关文章

  • 数据结构(双向链表的实现)
    目录一:带头双向链表什么叫双向链表:二:实现声明结构体(1).创建头结点进行初始化(2).动态申请一个结点(3).插入头插入:尾插入指定位置插入(中间插入)4:删除:头删除:尾删除:中间删除:5:打印链表一:带头双向链表什么叫双向链表:结点互相指向的,首结点指向null,尾结点指向null。如果想要提高单......
  • 双向循环连链表的另类实现
    `#include<stdio.h>include<stdlib.h>/**@filename: Untitled-1.c@brief双向链表的另类实现@[email protected]@date2024/04/[email protected]:版本@property:属性介绍@noteCopyRight(c)[email protected]*/typed......
  • 双向循环链表:(创建、插入、遍历、求长、查找、删除、排序、销毁)待测
    目录一、双向循环链表存在的意义二、节点的定义三:实现1:创建链表(即创建一个空链表)2:创建新结点3:遍历4:插入头插入尾插入中间插入一、双向循环链表存在的意义数组这样的结构提供了连续内存的访问和使用,链表是对内存零碎空间的有效组织和使用,双向循环链表增大了访问的自由度。二、......
  • 数据结构-双循环链表的插入
    数据结构-双循环链表插入/*************************************************/***@filename: DcirLLinkInsert*@brief对双向循环链表插入的功能实现*@[email protected]*@date2024/04/24*@version1.0:在下坂本,有何贵干*@property:none......
  • 单向链表的插入、与删除
    链表在C语言中,链表是一种常用的数据结构,它可以用来存储一系列的元素。链表中的每个元素都存储了下一个元素的地址,从而形成了一条链。这种结构使得在插入和删除元素时不需要像数组那样移动大量元素,因此它在插入和删除操作多的情况下有很大的优势。在C语言中,链表可以有多种实现方......
  • 数据结构-双循环链表的插入
    数据结构-双循环链表插入/*************************************************/***@filename: DcirLLinkInsert*@brief对双向循环链表插入的功能实现*@[email protected]*@date2024/04/24*@version1.0:在下坂本,有何贵干*@property:none......
  • DRF之全局异常处理、接口文档书写
    一、全局异常处理1、drf默认异常处理源码分析在DRF中,继承APIView后,它的执行流程是首先去除了所有请求的csrf认证,然后把视图类的request对象变成了新的request对象,新的reqeust对象是DRF的,但是以前Django的request对象用起来是一样的,同时把新的reqeust对象放到了视图类的对象中,然......
  • 单向循环链表大纲
    单向循环链表大纲/*************************************************************filename:*author:[email protected]*date:2024/04/23*function:*note:None**CopyRight(c)2023-20241987032607......
  • 接口脚本编写
     如果返回值是一个列表,而你需要从中根据判断条件获取对应的值 //假设响应体中的数据是一个列表,如下://[//{"id":1,"name":"Alice"},//{"id":2,"name":"Bob"},//{"id":3,"name":"Charlie"}......
  • jmeter有很多个接口需要用到token,怎么简单操作?
     一、实现方法添加HTTP请求默认值:在你的测试计划中,添加一个HTTP请求默认值配置元件(HTTPRequestDefaults),用于设置所有HTTP请求的公共属性,包括服务器地址、端口号等。你可以在这里设置token,以便在所有请求中都能使用它。获取token:在测试计划中,添加一个HTTP请求,......