双向循环链表 增删改查

双向循环链表

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

     

1

 

后来查了一下讲的双向循环链表都是这样的,不要被博主带偏

今天遇到了一段很喜欢的话,----------去日不可追,来日犹可期

 

下面是代码,还差  删和改  

/*************************************************************************
*   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);
}

 

 

posted @ 2025-05-17 23:04  记得要好好吃饭  阅读(15)  评论(0)    收藏  举报