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;
}
相关推荐
Tairitsu_H10 小时前
[Linux系统] 基础IO核心 | 系统接口 | 文件描述符 | 重定向
linux·服务器·文件操作
嵌入式-老费10 小时前
esp32开发与应用(用Python+PySide6解决上位机开发)
linux·单片机·嵌入式硬件
事已至此先睡覺吧11 小时前
(三)Linux 基础指令(二):基础常用的一些指令
linux·运维·服务器
MI_farmer11 小时前
Anaconda 安装在 D 盘但虚拟环境跑到 C 盘,以及 Conda PermissionError: WinError 5 的解决方法
c语言·开发语言·conda
ShineWinsu11 小时前
对于Redis:Redis的认识以及分布式系统的解析
linux·数据库·c++·redis·缓存·消息队列·分布式架构
Zenova EdgeOS12 小时前
Linux IO 监测:iotop 工业边缘排障实战
linux·边缘计算·工业网关·iotop·排障
Fcy64812 小时前
Linux下 传输层协议UDP详解(含底层源码解析)
linux·运维·udp
优质酸酸乳12 小时前
力扣100题之21合并两个有序链表
算法·leetcode·链表
青梅味猪大肠12 小时前
【操作系统-24】双标志先检查
linux·运维·服务器
xiaoye-duck12 小时前
《Linux 网络编程》深入理解五种 IO 模型:从 IO 本质到非阻塞 IO 实战
linux·网络