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;
}
相关推荐
你怎么知道我是队长7 小时前
C语言---枚举变量
c语言·开发语言
晚枫歌F7 小时前
Dpdk介绍
linux·服务器
POLITE38 小时前
Leetcode 23. 合并 K 个升序链表 (Day 12)
算法·leetcode·链表
工程师老罗10 小时前
龙芯2k0300 PMON取消Linux自启动
linux·运维·服务器
千百元10 小时前
centos如何删除恶心定时任务
linux·运维·centos
2401_8769075212 小时前
USB TYPE-C 公头连接器设计规范总结:提升可靠性、降本增效的关键指南
c语言·开发语言·设计规范
oMcLin12 小时前
如何在Manjaro Linux上配置并优化Caddy Web服务器,确保高并发流量下的稳定性与安全性?
linux·服务器·前端
济61712 小时前
linux(第七期)--gcc编译软件-- Ubuntu20.04
linux·运维·服务器
天赐学c语言12 小时前
1.7 - 删除排序链表中的重要元素II && 哈希冲突常用解决冲突方法
数据结构·c++·链表·哈希算法·leecode
corpse201013 小时前
Linux监控软件Monitorix 安装部署
linux·安全