C语言实现循环链表demo

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

typedef struct Node{
    int data;
    struct Node *prev;
    struct Node *next;
}Node;

typedef struct double_link_list{
    Node* head;
    int length;
}double_link_list;


Node* creat_node(int data)
{
    Node* new_node = (Node*)malloc(sizeof(Node));
    if(NULL == new_node)
    {
        perror("malloc new node error");
        return NULL;
    }
    new_node->data = data;
    new_node->prev = new_node;//指向自己
    new_node->next = new_node;
    return new_node;
}

double_link_list* dll_init()
{
    double_link_list* list = (double_link_list*)malloc(sizeof(double_link_list));
    if(NULL == list)
    {
        perror("malloc list error");
        return NULL;
    }
    Node* head = (Node*)creat_node(0);
    if(NULL == head)
    {
        perror("creat head error");
        return NULL;
    }
    list->head = head;
    list->length = 0;
    return list;
}

/*
    头插法:在头节点和第一个有效节点之间插入
*/
int dll_insert_head(double_link_list* list,int data)
{
    if(NULL == list)
    {
        printf("list is NULL and return\n");
        return -1;
    }
    Node* new_node = creat_node(data);
    if(NULL == new_node)
    {
        return -1;
    }
    new_node->next = list->head->next;
    new_node->prev = list->head;
    list->head->next->prev = new_node;
    list->head->next = new_node;
    
    
    list->length++;

    return 0;
}

/*
    尾插法
*/
int dll_insert_tail(double_link_list* list,int data)
{
    if(NULL == list)
    {
        printf("list is NULL and return\n");
        return -1;
    }
    Node* new_node = creat_node(data);
    if(NULL == new_node)
    {
        return -1;
    }
    new_node->next = list->head;
    new_node->prev = list->head->prev;
    list->head->prev->next = new_node;
    list->head->prev = new_node;
    
    list->length++;

    return 0;
}

void dll_destory(double_link_list* list)
{   
    if (list == NULL) 
    {
        return;
    }

    Node* curr = list->head->next;
    Node* temp = NULL;

    while(list->head != curr)
    {
        temp = curr;
        curr = curr->next;
        free(temp);
        temp = NULL;
    }

    free(list->head);
    list->head = NULL;
    free(list);
    list = NULL;
    printf("list is destory\n");
}

void dll_print(double_link_list* list)
{
    if (list == NULL) 
    {
        return;
    }

    Node* curr = list->head->next;
    while(curr != list->head)
    {
        printf("curr->data = %d\n",curr->data);
        curr = curr->next;
    }
}

// 按值删除:删除第一个匹配data的节点
int dll_delete_val(double_link_list* list, int data) 
{
    if (list == NULL || list->length == 0) {
        printf("链表为空,无法删除\n");
        return -1;
    }
    Node* curr = list->head->next;

    while(curr != list->head)
    {
        if(curr->data == data)
        {
            curr->prev->next = curr->next;
            curr->next->prev = curr->prev;
            free(curr);
            curr = NULL;
            list->length--;
            printf("成功删除值为%d的节点\n", data);
            return 0;
        }
        curr = curr->next;
    }

    printf("未找到值为%d的节点\n", data);
    return -1;

}

// 按位置删除:pos从1开始
int dll_delete_pos(double_link_list* list, int pos) 
{
    if (list == NULL || list->length == 0) {
        printf("链表为空,无法删除\n");
        return -1;
    }
    if (pos < 1 || pos > list->length) {
        printf("删除位置非法(pos范围:1~%d)\n", list->length);
        return -1;
    }

    Node* curr = list->head->next;
    for(int i = 1;i < pos;i++)
    {
        curr = curr->next;
    }

    curr->prev->next = curr->next;
    curr->next->prev = curr->prev;
    free(curr);
    curr = NULL;
    list->length--;
    printf("成功删除位置%d的节点\n", pos);
    return 0;
}

int main()
{
    
    double_link_list* list = NULL;
    int ret = 0;

    list = dll_init();
    if (list == NULL) 
    {
        return -1;
    }   

    ret = dll_insert_head(list,100);
    if(ret != 0)
    {
        printf("dll_insert_head error\n");
        return -1;
    }
    ret = dll_insert_head(list,666);
    if(ret != 0)
    {
        printf("dll_insert_head error\n");
        return -1;
    }

    ret = dll_insert_head(list,9999);
    if(ret != 0)
    {
        printf("dll_insert_head error\n");
        return -1;
    }

    ret = dll_insert_tail(list,8888);
    if(ret != 0)
    {
        printf("dll_insert_head error\n");
        return -1;
    }


    dll_print(list);
    sleep(1);
    dll_delete_val(list, 9999) ;
    dll_print(list);
    sleep(1);
    dll_delete_pos(list,list->length);
    dll_print(list);
    
    dll_destory(list);

    return 0;
}
相关推荐
三品吉他手会点灯10 小时前
C语言学习笔记 - 50.流程控制4 - 流程控制为什么非常非常重要
c语言·开发语言·笔记·学习
影视飓风TIM13 小时前
数据结构 | 链表超全笔记(单链表+双链表+高频算法题)
数据结构·笔记·链表
十月的皮皮14 小时前
C语言学习笔记20260615-有序升序序列合并
c语言·笔记·学习
暮云星影14 小时前
全志linux开发屏幕适配(一)屏幕参数设置说明
linux·arm开发
swordbob15 小时前
NIO 的 Channel 里有多个 BIO 吗?
linux·网络·nio
Fcy64815 小时前
Linux下 信号的保存与捕捉
linux·中断·信号的捕捉·信号的保存
A_humble_scholar16 小时前
Linux(九) 进程管理完全指南:从入门到实战
linux·运维·chrome
江华森16 小时前
Linux 操作命令完全指南
linux·运维
玖玥拾16 小时前
C/C++ 数据结构(六)链表迭代器与底层
c语言·数据结构·c++·链表·stl库
rjszcb17 小时前
Linux,sensor调试笔记1,修改帧率,以及曝光上不去问题
linux