首页 > 其他分享 >数据结构:双向循环链表的创建·插入·删除

数据结构:双向循环链表的创建·插入·删除

时间:2024-04-25 09:38:14浏览次数:19  
标签:current Head next 链表 LList 双向 CirDou New 数据结构

数据结构:双向循环链表的创建·插入·删除

/**
  * @file name : 数据结构:双向循环链表的创建·插入·删除
  * @brief     : 实现双向循环链表的创建·插入·删除
  * @author	   : [email protected]
  * @date 	   :2024/04/24
  * @version   :1.0
  * @note      :none
  * CopyRight(c):  2023-2024   [email protected]   All Right Reseverd
  */
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  //定义节点中的数据域类型
  typedef int Data_t;
  //定义一个节点类型
  typedef struct CircularDoul_LList{
  	Data_t data;
  	struct CircularDoul_LList *next;
  	struct CircularDoul_LList *prev;
  }CirDou_LList_t;
  //创建一个空链表
/**
  * @function: CirDou_LList_Creat
  * @brief   : 创建一个空链表
  * @param   : 空
  * @retval  : @CirDou_LList_t,返回该链表的地址
  * @date    : 2024/04/24
  * @version : 1.0 
  * @note    : none
  * author   : [email protected]
  */
  CirDou_LList_t *CirDou_LList_Creat()
  {
  	CirDou_LList_t *Head=calloc(1,sizeof(  CirDou_LList_t ));//申请一个内存
  	//判断内存是否申请成功
  	if(NULL==Head)
  	{
  		perror("calloc memory for Head is failed");
  		return NULL;
  	}
  	//初始化成员变量
  	Head->next=Head;//连着自身
	Head->prev=NULL;
  	return Head;
 //创建一个新节点
  /**
  * @function: CirDou_LListNode_Creat
  * @brief   : 创建一个新节点
  * @param   : @Data_t data:接收数据域的值
  * @retval  : @CirDou_LList_t:返回该节点的地址
  * @date    : 2024/04/24
  * @version : 1.0 
  * @note    : none
  * author   : [email protected]
  */
 CirDoul_LList_t* CirDou_LListNode_Creat(Data_t data)
  {
  	CirDou_LList_t *New=calloc(1,sizeof(  CirDou_LList_t ));//定义节点并申请内存
  	//判断内存是否申请成功
  	if(NULL==New)
  	{
  		perror("calloc memory for New is failed");
  		return NULL;
  	}
  	//初始化成员变量
  	New->next=Null;
	New->prev=NULL;
  	New->data=data;
  	return New;
  }
  //判断链表是否为空
  /**
  * @function: CirDou_LList_IsEmpoty
  * @brief   : 判断链表是否为空
  * @param   : @CirDou_LList_t *Head:需要判断的链表
  * @retval  : @bool:已满返回ture,未满返回false
  * @date    : 2024/04/24
  * @version : 1.0 
  * @note    : none
  * author   : [email protected]
  */
  bool CirDou_LList_IsEmpoty(CirDou_LList_t *Head)
  {
  	if(Head->next==Head)
  	{
  		return ture;
  	}
  	return false;
  }
  //1.尾部插入节点
  /**
  * @function: CirDou_LList_TailInsert
  * @brief   : 尾部插入节点
  * @param   : @ CirDou_LList_t *Head:需要被插入的链表
  			 : @ Data_t data:要插入节点的数据域
  * @retval  : @bool:插入返回ture,未插入返回false
  * @date    : 2024/04/24
  * @version : 1.0 
  * @note    : none
  * author   : [email protected]
  */
 bool  CirDou_LList_TailInsert(CirDou_LList_t *Head,Data_t data)
 {
 	CirDoul_LList_t* New=CirDou_LListNode_Creat(Data_t data)//得到要插入的节点
 	if(NULL==New)
 	{
 		return false;
 	}
 	//链表为空的情况
 	if(CirDou_LList_IsEmpoty(CirDou_LList_t *Head))
 	{
 		New->prev=New;//前驱和后继都连本身
 		Head->next=New;
 		New->next=New;
 		return ture;
 	}
 	//若不为空时
 	New->prev=Head->next->prev;
 	New->next=Head->next;
 	Head->next->prev->next=New;
 	Head->next->prev=New;
 	return ture;
 }
 //2.头部插入节点
  /**
  * @function: CirDou_LList_HeadInsert
  * @brief   : 尾部插入节点
  * @param   : @ CirDou_LList_t *Head:需要被插入的链表
             : @ Data_t data:要插入节点的数据域
  * @retval  : @bool:插入返回ture,未插入返回false
  * @date    : 2024/04/24
  * @version : 1.0 
  * @note    : none
  * author   : [email protected]
  */
 bool  CirDou_LList_HeadInsert(CirDou_LList_t *Head,Data_t data)
 {
 	CirDoul_LList_t* New=CirDou_LListNode_Creat(Data_t data)//得到要插入的节点
 	if(NULL==New)
 	{
 		return false;
 	}
 	//链表为空的情况
 	if(CirDou_LList_IsEmpoty(CirDou_LList_t *Head))
 	{
 		New->prev=New;//前驱和后继都连本身
 		Head->next=New;
 		New->next=New;
 		return ture;
 	}
 	//若不为空时
 	New->next=Head->next;
 	New->prev=Head->next->prev;
 	Head->next->prev->next=New;
 	Head->next->prev=New;
 	Head->next=New;
 	return ture;
 }
 //3.指定位置插入节点
  /**
  * @function: CirDou_LList_DestInsert
  * @brief   : 尾部插入节点
  * @param   : @ CirDou_LList_t *Head:需要被插入的链表
  			 : @Data_t data1:指定要插入位置的节点数据域
  			 : @ Data_t data:要插入节点的数据域
  * @retval  : @bool:插入返回ture,未插入返回false
  * @date    : 2024/04/24
  * @version : 1.0 
  * @note    : none
  * author   : [email protected]
  */
 bool  CirDou_LList_DestInsert(CirDou_LList_t *Head,Data_t data1,Data_t data)
 {
 	CirDou_LList_t *Dest=CirDou_LListNode_Create (Data_t data1);//要被删除的节点
 	CirDoul_LList_t * New=CirDou_LListNode_Creat(Data_t data)//得到要插入的节点
 	CirDoul_LList_t* current=Head->next;//备份首节点的地址
 	if(NULL==New)
 	{
 		return false;
 	}
 	//链表为空的情况
 	if(CirDou_LList_IsEmpoty(CirDou_LList_t *Head))
 	{
 		New->prev=New;//前驱和后继都连本身
 		Head->next=New;
 		New->next=New;
 		return ture;
 	}
 	//若不为空时
 	while(current->data==Dest->data)
 	{		
 	//当刚好插到尾部时
 		if(current->next==Head->next)
 		{
 			current->next=New;
 			New->next=Head->next;
 			Head->prev=New;
 			reture ture;
 		}
 	//插在中间
 		else
 		{	New->next=current->next;
 			New->prev=current;
 			current->next->prev=New;
 			current->next=New;
            return ture;
 		}
 		current=current->next;
 	}
 	
 }
 //从头部删除节点
/**
  * @function: CirDou_LList_HeadDel
  * @brief   : 从头部删除节点
  * @param   : @ CirDou_LList_t *Head:需要被删的链表
  * @retval  : @bool:删除返回ture,未删除返回false
  * @date    : 2024/04/24
  * @version : 1.0 
  * @note    : none
  * author   : [email protected]
  */
 bool CirDou_LList_HeadDel(CirDou_LList_t *Head)
 {
 	CirDou_LList_t *current=Head->next;备份首节点
  //如果链表为空
 	if(CirDou_LList_IsEmpoty(CirDou_LList_t *Head))
 	{
 		print("link is empoty");
 		return false;
 	}
 	//如果链表不为空
 	current->prev->next=current->next;
 	current->next->prev=current->prev;
 	Head->next=current->next;
 	current->next=NULL;
 	current->prev=NULL;
 	free(current);
 	return ture;
 }
  //从尾部删除节点
/**
  * @function: CirDou_LList_TailDel
  * @brief   : 从尾部删除节点
  * @param   : @ CirDou_LList_t *Head:需要被删的链表
  * @retval  : @bool:删除返回ture,未删除返回false
  * @date    : 2024/04/24
  * @version : 1.0 
  * @note    : none
  * author   : [email protected]
  */
 bool CirDou_LList_TailDel(CirDou_LList_t *Head)
 {
 	CirDou_LList_t *Tail=Head->next->prev;备份尾节点地址
  //如果链表为空
 	if(CirDou_LList_IsEmpoty(CirDou_LList_t *Head))
 	{
 		print("link is empoty");
 		return false;
 	}
 //如果链表不为空
 	Tail->next=NULL;
 	Tail->prev->next=Head->next;
 	Head->next->prev=Tail->prev
 	Tail->prev=	NULL;
 	free(Tail);
 	return ture;
 }
 //删除指定节点
/**
  * @function: CirDou_LList_DestDel
  * @brief   : 删除指定节点
  * @param   : @ CirDou_LList_t *Head:需要被删的链表
  			 : @ Data_t data: 要被删除的节点数据域
  * @retval  : @bool:删除返回ture,未删除返回false
  * @date    : 2024/04/24
  * @version : 1.0 
  * @note    : none
  * author   : [email protected]
  */
 bool CirDou_LList_TailDel(CirDou_LList_t *Head,Data_t data)
 {
 	CirDou_LList_t *Dest=CirDou_LListNode_Creat(Data_t data)
 	CirDou_LList_t *current=Head->next;//记录当前节点
  //如果链表为空  
 	if(CirDou_LList_IsEmpoty(CirDou_LList_t *Head))
 	{
 		print("link is empoty");
 		return false;
 	}
 //如果链表不为空
 	while(current->data==Dest->data)
 	{
 		//1.删除的恰好是首节点
 		if(Head->next==current)
 		{
 		 	//链表有多个节点的情况
 			if(current->next!=current)
 			{
 				current->prev->next=current->next;
 				current->next->prev=current->prev;
 				Head->next=current->next;
 				current->next=NULL;
 				current->prev=NULL;
 				free(current);
 				return ture;
 			}
 			//链表只有一个首节点的情况
 			current->next=NULL;
 			current->prev=NULL;
 			Head->next=Head;
 			free(current);
 			return ture;		
 		}
 		//2.删除的恰好是尾节点
 		if(current->next==Head->next)
 		{
 			current->next=NULL;
 			current->prev->next=Head->next;
 			Head->next->prev=current->prev;
 			current->prev=NULL;
 			free(current);
 			return ture;
 		}
 		//3.删除中间的节点
 		else
 		{
 			current->prev->next=current->next;
 			current->next->prev=current->prev;
 			current->prev=NULL;
 			current->next=NULL;
 			free(current);
 			return ture;
 		}
 	  current=current->next; 	
   }
 }
 /**
  * @function: CirDou_LList_Print
  * @brief   : 打印链表
  * @param   : @ CirDou_LList_t *Head:需要被打印的链表
  			 
  * @retval  : 空
  * @date    : 2024/04/24
  * @version : 1.0 
  * @note    : none
  * author   : [email protected]
  */
 void CirDou_LList_Print(CirDou_LList_t *Head)
 {
 	CirDou_LList_t *current=Head->next;记录当前节点
 	while(current!=current->next)
 	{
 		printf("%d\n",current->data);
 		current=current->next;
 	}
 }
 //进行测试,验证代码是否正确
 int main()
 {
 //创建一个空链表
 	CirDou_LList_t *Head=CirDou_LList_Create();
 //从尾部插入节点
 	CirDou_LList_TailInsert(Head,10);
 	CirDou_LList_TailInsert(Head,20);
 	CirDou_LList_TailInsert(Head,30);
 	CirDou_LList_TailInsert(Head,40);
 //遍历一遍并打印出来
 	CirDou_LList_Print(CirDou_LList_t *Head);
 //从头部插入节点
 	CirDou_LList_HeadInsert(Head,1);
 	CirDou_LList_HeadInsert(Head,2);
 	CirDou_LList_HeadInsert(Head,3);
 	CirDou_LList_HeadInsert(Head,4);
 //遍历一遍并打印出来
 	CirDou_LList_Print(CirDou_LList_t *Head);
 //从指定位置插入节点
 	CirDou_LList_DestInsert(Head,1,6);
 	CirDou_LList_HeadInsert(Head,2,7);
 	CirDou_LList_HeadInsert(Head,3,8);
 	CirDou_LList_HeadInsert(Head,4,9);
 //遍历一遍并打印出来
 	CirDou_LList_Print(CirDou_LList_t *Head);
 //从头部删除节点
	 CirDou_LList_HeadDel(Head);
	 CirDou_LList_HeadDel(Head);
 //遍历一遍并打印出来
 	CirDou_LList_Print(CirDou_LList_t *Head);
 //从尾部删除节点
     CirDou_LList_TailDel(Head);
     CirDou_LList_TailDel(Head);
 //遍历一遍并打印出来
 	CirDou_LList_Print(CirDou_LList_t *Head);
  //从指定位置删除节点
 	 CirDou_LList_DestDel(Head,20);
 	 CirDou_LList_DestDel(Head,30);
  //遍历一遍并打印出来
 	CirDou_LList_Print(CirDou_LList_t *Head);
 	return 0;
 }

标签:current,Head,next,链表,LList,双向,CirDou,New,数据结构
From: https://www.cnblogs.com/liuliuye/p/18156872

相关文章

  • 双向循环链表
    双向循环链表原理与应用双向循环链表与双向链表的区别:指的是双向循环链表的首结点中的prev指针成员指向链表的尾结点,并且双向循环链表的尾结点里的next指针成员指向链表的首结点,所以双向循环链表也属于环形结构。双向循环链表各功能实现(1)为了管理双向循环链表,需要构造头结点......
  • 数据结构:双向链表的创建·插入·删除
    数据结构:双向链表的创建·插入·删除/***@filename:数据结构:双向链表的创建·插入·删除*@brief:实现双向链表的创建·插入·删除*@author :[email protected]*@date :2024/04/23*@version:1.0*@note:none*CopyRight(c......
  • 反转链表
    packagemainimport"fmt"typeListNodestruct{ValintNext*ListNode}funcreverseList(head*ListNode)*ListNode{ifhead==nil||head.Next==nil{returnhead}newHead:=reverseList(head.Next)he......
  • 双向循环链表
    /**********************************************************************************************************设计双向链表的接口******************************************************************************************************/include<stdio.h>i......
  • 双向链表和双向循环链表的(创建、插入、删除、遍历)
    V1.02024年4月24日发布于博客园目录目录目录双向链表和双向循环链表的(创建、插入、删除、遍历)设计双向链表的接口创建一个空的双向链表,空链表应该有一个头结点,对链表进行初始化创建新的结点,并对新结点进行初始化(数据域+指针域)创建一个新的结点进行头部插入创建一个新的......
  • 用一个尽可能高效的算法,查找单向链表(有头结点)中倒数第k个位置上的结点
    思路  定义两个指向链表首结点的指针变量,第一个指针变量向后移动k个位置后,第二个指针变量也开始跟着一起向后移动,直到第一个指针变量指向尾结点为止,第二个指针变量指向的位置结点就是倒数第k个结点。实现步骤及参考代码(C语言)intLList_FindLK(LList_t*Head,DataType_tda......
  • 自定义双向循环链表基本函数接口
    自定义双向循环链表的函数接口/********************************************************************* 文件名称: 双向循环链表的函数接口* 文件作者:[email protected]* 创建日期:2024/04/24* 文件功能:对双向链表的增删改查功能的定义* 注意事项:No......
  • 双向循环链表及各功能函数设计
    双向循环链表/***@filename:双向链表接口设计*@brief*@[email protected]*@date2024/04/24*@version1.0:版本*@property:*@note*CopyRight(c)[email protected]*/构造双向循环链表的结点//指的是双向循......
  • 设计双向链表的接口
    /***********************************************************************************filename:004_双向链表.cauthor:[email protected]:2024/04/24function:设计双向循环链表的接口note:None......
  • 数据结构(双向链表的实现)
    目录一:带头双向链表什么叫双向链表:二:实现声明结构体(1).创建头结点进行初始化(2).动态申请一个结点(3).插入头插入:尾插入指定位置插入(中间插入)4:删除:头删除:尾删除:中间删除:5:打印链表一:带头双向链表什么叫双向链表:结点互相指向的,首结点指向null,尾结点指向null。如果想要提高单......