双向循环链表 增删改查
双向循环链表
- 双向链表(Doubly Linked List)是一种常见的链表数据结构。它与普通链表的区别在于,每个节点都有两个指针,一个指向前一个节点,一个指向后一个节点,因此可以从任意一个节点开始,双向遍历整个链表。
- 博主对于头结点是否进入循环还一些疑惑,不过经过对于代码的构建发现还是放入循环后,方便一些!

后来查了一下讲的双向循环链表都是这样的,不要被博主带偏
今天遇到了一段很喜欢的话,----------去日不可追,来日犹可期

下面是代码,还差 删和改
/*************************************************************************
* file name:doublecyclelist
* function: 实现对双向链表的增删改查功能
* date: 2025.5.16
* note:none
* Copyright (c) 2024-2025 l550036303@163.com All right reserved
**************************************************************************/
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
typedef int datetype;
typedef struct doublecyclelist{
datetype date;
struct doublecyclelist * prev;
struct doublecyclelist * next;
}doublecycl_t;
/*************************************************************************
* name: doublecycl_t_creat
* brief: 简介:用于创建并初始化头结点
* param:
* none
* retval: 返回指向头结点的指针,类型和结点类型相同
* date: 2025.5.17
* version:v1.0
* note: none
**************************************************************************/
doublecycl_t * doublecycl_t_creat(){
doublecycl_t *head = (doublecycl_t *)calloc(1,sizeof(doublecycl_t));
head->next = head;
head->prev = head;
return head;
}
/*************************************************************************
* name: doublecycl_t_newnode
* brief: 简介:用于创建并初始化新的节点
* param:
* @date 结点内要添加的数据
* retval: 返回指向新结点的指针,类型和结点类型相同
* date: 2025.5.15
* version:v1.0
* note: 被doublecycl_t_add_last函数调用使用,所以date数据交给doublecycl_t_add_last函数即可
**************************************************************************/
doublecycl_t * doublecycl_t_newnode(datetype date){
doublecycl_t *new = (doublecycl_t *)calloc(1,sizeof(doublecycl_t));
new->next=NULL;
new->prev=NULL;
new->date=date;
return new;
}
/*************************************************************************
* name:doublecycl_t_IsEmpty
* function:判断此栈是否为空,还有没有元素
* argument:
* @head 需要判断的链表
* reval: 以布尔类型返回结果
* true 还有空间
* false没有空间了
* date: 2025.5.17
* note:none
**************************************************************************/
bool doublecycl_t_IsEmpty(doublecycl_t * head){
return (head == head->next) ? true : false ;
}
/*************************************************************************
* name: doublecycl_t_add_last
* brief: 简介:在当前链表的最后添加新的节点
* param:
* @head 要添加数据的链表
* @date 所添加的新结点内要添加的数据
* retval: 返回bool结果,用于判断是否成功添加
* date: 2025.5.17
* version:v1.0
* note: 本函数中调用了doublecycl_t_newnode来创建新结点,详细见doublecycl_t_newnode函数
**************************************************************************/
bool doublecycl_t_add_last(doublecycl_t * head,datetype date){
doublecycl_t * new = doublecycl_t_newnode(date);
doublecycl_t * temp = head -> next;
//1、考虑双向循环链表只有一个头结点的情况、插入首结点
if(doublecycl_t_IsEmpty(head)){
head->next=new;
new->next=new;
new->prev = new;
printf("\tfirst\tadd\tsuccess\n");
return true;
}
//2、寻找尾结点
while(temp->next != head->next){
temp=temp->next;
}
temp->next = new;
new->prev = temp;
new->next = head->next;
printf("\tlast\tadd\tsuccess\n");
return true;
}
/*************************************************************************
* name: doublecycl_t_add_Top
* brief: 简介:在当前链表的头结点后添加新的节点
* param:
* @head 要添加数据的链表
* @date 所添加的新结点内要添加的数据
* retval: 返回bool结果,用于判断是否成功添加
* date: 2025.5.17
* version:v1.0
* note: 本函数中调用了doublecycl_t_newnode来创建新结点,详细见doublecycl_t_newnode函数
**************************************************************************/
bool doublecycl_t_add_Top(doublecycl_t * head,datetype date){
doublecycl_t * new = doublecycl_t_newnode(date);
doublecycl_t * temp = head -> next;
//1、考虑双向循环链表只有一个头结点的情况、插入首结点
if(doublecycl_t_IsEmpty(head)){
head->next=new;
new->next=new;
new->prev =new;
printf("\tfirst\tadd\tsuccess\n");
return true;
}
//2、在头结点后插入
while( temp ->next != head->next ){
temp = temp -> next ;
}
new->next = head->next;
new->next->prev = new;
head->next = new;
temp->next = new;
new->prev = temp;
printf("\tTop\tadd\tsuccess\n");
return true;
}
/*************************************************************************
* name: doublecycl_t_add_appoint
* brief: 简介:在当前链表的指定位置添加新的节点
* 0 1 2 3 4 5 插入K在3位置 0 1 2 3 4 5 6
* a b c d e f a b c K d e f
* param:
* @head 要添加数据的链表
* @date 所添加的新结点内要添加的数据
* @location 要添加的位置
* retval: 返回bool结果,用于判断是否成功添加
* date: 2025.5.17
* version:v1.0
* note: 本函数中调用了doublecycl_t_newnode来创建新结点,详细见doublecycl_t_newnode函数
**************************************************************************/
bool doublecycl_t_add_appoint(doublecycl_t * head,datetype date,int location){
doublecycl_t * new = doublecycl_t_newnode(date);
doublecycl_t * temp = head -> next;
//1、考虑双向循环链表只有一个头结点的情况、插入首结点
if(doublecycl_t_IsEmpty(head)){
head->next=new;
new->next=new;
new->prev = new;
printf("\tfirst\tadd\tsuccess\n");
return true;
}
if( location == 1 ){
doublecycl_t_add_Top(head,date);
return true;
}
//2、在location位置结点后插入
// 第一种想法
// int i = 1;
// while( temp ->next != head->next && (i < location) ){
// temp = temp -> next ;
// i++;
// }
// // 第二种想法 方式location的值超过循环数组的长度所以限制
while( temp->next != head->next && (location > 2) ){
temp = temp->next ;
location--;
}
//判断所插入的位置是不是在最后,ture 就是尾插
if( temp->next == head->next){
new->next = temp->next;
temp->next = new;
new->prev = temp;
return true;
}
//false 所插入在中间
new->next = temp->next;
new->prev = temp;
temp->next->prev = new;
temp->next = new;
printf("\tlocation\tadd\tsuccess\n");
return true;
}
// 递归思想...未成功
// bool doublecycl_t_print_cycle(doublecycl_t * head,doublecycl_t * temp){
// if(doublecycl_t_IsEmpty(head)){
// return false;
// }
// printf("%d\n",head->date);
// if(head == temp){
// return false;
// }
// doublecycl_t_print_cycle(head->next,temp);
// }
/*************************************************************************
* name:doublecycl_t_print
* function:打印该栈中的元素
* argument:
* @manager 需要打印的链表
* reval: 以布尔类型返回结果
* true打印成功
* false打印失败,出现问题
* date: 2025.5.17
* note:none
**************************************************************************/
bool doublecycl_t_print(doublecycl_t * head){
doublecycl_t * temp = head;
if(doublecycl_t_IsEmpty(head)){
printf("\tthis DoubleCycleLinkList is empty\n");
return false;
}
int i=1;
do{
temp = temp->next;
printf("\t%d\tdate=%d\n",i,temp->date);
i++;
}while(temp->next != head->next);
return true;
}
//废弃函数 打印只能通过来 do while 解决
// bool doublecycl_t_print_pro(doublecycl_t * head){
// doublecycl_t * temp = head->next;
// int i=0;
// while(temp->next != head->next){
// printf("\t%d\tdate=%d\n",i,temp->date);
// temp = temp->next;
// i++;
// }
// return true;
// }
int main(int agrc ,char const *agrv[]){
doublecycl_t * head= doublecycl_t_creat();
doublecycl_t_add_last(head,1);
doublecycl_t_add_last(head,2);
doublecycl_t_add_last(head,4);
doublecycl_t_add_last(head,5);
// doublecycl_t_add_last(head,5);
// doublecycl_t_add_last(head,6);
//doublecycl_t_print(head);
// doublecycl_t_add_Top(head,100);
// doublecycl_t_add_Top(head,200);
// doublecycl_t_add_Top(head,300);
// doublecycl_t_add_last(head,4);
//doublecycl_t_add_appoint(head,5000,20);
// doublecycl_t_add_appoint(head,0,1);
doublecycl_t_add_appoint(head,3,3);
doublecycl_t_add_appoint(head,1000,4);
// doublecycl_t_add_appoint(head,4,4);
// doublecycl_t_add_appoint(head,7,20);
// doublecycl_t_add_appoint(head,8,30);s
// doublecycl_t_add_appoint(head,1000,2);
// doublecycl_t_add_appoint(head,1000,2);
doublecycl_t_print(head);
}

浙公网安备 33010602011771号