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;
}
相关推荐
_F_y8 小时前
MySQL用C/C++连接
c语言·c++·mysql
BackCatK Chen8 小时前
C语言学习栏目目录
c语言·保姆级教程·c语言入门·c语言学习栏目目录
微露清风8 小时前
系统性学习Linux-第二讲-基础开发工具
linux·运维·学习
不会代码的小猴9 小时前
Linux环境编程第六天笔记--system-V IPC
linux·笔记
阳光九叶草LXGZXJ9 小时前
达梦数据库-学习-48-DmDrs控制台命令(同步之Manager、CPT模块)
linux·运维·数据库·sql·学习
诸神缄默不语9 小时前
Linux命令行教程
linux
极客数模10 小时前
【2026美赛赛题初步翻译F题】2026_ICM_Problem_F
大数据·c语言·python·数学建模·matlab
i建模11 小时前
如何在Arch Linux中重设忘记的root密码
linux·运维·服务器
kida_yuan12 小时前
【Linux】运维实战笔记 — 我常用的方法与命令
linux·运维·笔记
@syh.12 小时前
【linux】进程控制
linux