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;
}
相关推荐
.柒宇.8 小时前
MySQL双主同步
linux·数据库·mysql·docker
格林威8 小时前
AI视觉检测:INT8 量化对工业视觉检测精度的影响
linux·运维·人工智能·数码相机·计算机视觉·视觉检测·工业相机
万山寒9 小时前
linux日志查询,查找某个关键词后面的内容
linux·运维·服务器
房开民9 小时前
ubuntu中安装claude code
linux·运维·ubuntu
Bert.Cai9 小时前
Linux mv命令详解
linux·运维
网域小星球9 小时前
C 语言从 0 入门(十七)|结构体指针 + 动态内存 + 文件综合实战
c语言·开发语言·文件操作·结构体指针·动态内存·综合项目
头铁的伦9 小时前
QNX 网络模型
linux·网络·车载系统
小贾要学习9 小时前
【Linux】TCP网络通信编程
linux·服务器·网络·c++·网络协议·tcp/ip
渣渣馬9 小时前
rk3588s的firfly的linux的sdk版本
linux·运维·服务器
lcj251110 小时前
【C语言】数据在内存中的存储
c语言·数据结构