数据结构:双向循环链表的创建·插入·删除
/**
* @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