数据结构系列4-双循环链表

实现功能:

  1. 双循环链表的创建
  2. 双循环链表的插入(头插法、尾插法)
  3. 双循环链表的删除
  4. 双循环链表的遍历

代码实现:

//双循环链表
#include <stdio.h>
#include <stdlib.h>

//定义链表节点的结构体
typedef struct node_st
{
    int data;  //数据域
    struct node_st *prev;  //前驱指针
    struct node_st *next;  //后继指针
}list;

/*函数声明部分*/
list *list_create();                    //链表的创建
void list_insert_h(list *head,int data);//头插法
void list_insert_t(list *head,int data);//尾插法
int list_delete(list *head,int data);   //链表的删除
void list_print(list *head);            //链表的遍历

int main()
{
    int i = 0;
    list *head = list_create();
    for(i=0;i<3;i++)
    {
        list_insert_h(head,i);
    }

     list_insert_t(head,3);
     list_insert_t(head,4);

     list_print(head);

     for(i=0;i<5;i++)
     {
        list_delete(head,i);
     }
     list_print(head);

    return 0;
}

/*函数实现部分*/
//链表的创建
list *list_create()
{
    list *head = malloc(sizeof(*head));//头节点

    head->data = 0;//记录有效节点个数
    head->prev = head;  //循环链表
    head->next = head;

    return head;  //返回头指针
}
//链表的插入-头插法
void list_insert_h(list *head,int data)
{
    list *new = malloc(sizeof(*new));//待插入的新节点
    new->data = data; //新节点的数据
    //1).链表为空
    if(head->data == 0)
    {
        new->prev = head;//1.新节点的前驱指针指向头节点
        new->next = head;//2.新节点的后继指针指向头节点
        head->prev = new;//3.头节点的前驱指针指向新节点
        head->next = new;//4.头节点的后继指针指向新节点
    }
    //2).链表不为空
    else
    {
        new->prev = head;//1.新节点的前驱指针指向头节点
        new->next = head->next;//2.新节点的后继指针指向第1个有效节点
        head->next = new;//3.头节点的后继指针指向新节点
        head->next->prev = new;//4.第1个有效节点的前驱指针指向新节点
    }
    head->data++;  //有效节点数+1
}
//尾插法
void list_insert_t(list *head,int data)
{
    list *new = malloc(sizeof(*new));
    list *tail = head;
    new->data = data;  //新节点数据

    while(tail->next != head)
    {
        tail = tail->next;
    }
    new->prev = tail;//1.新节点的前驱指针指向尾节点
    new->next = head;//2.新节点的后继指针指向头节点
    head->prev = new;//3.头节点的前驱指针指向新节点
    tail->next = new;//4.尾节点的后继指针指向新节点

    head->data++; //有效节点数+1
}
//链表的删除
int list_delete(list *head,int data)
{
    list *node = head->next;
    while(node != head)
    {
        if(node->data == data)
        {
        //待删节点的前1节点的后继指针指向待删节点的后1节点
            node->prev->next = node->next;
        //待删节点的后1节点的前驱指针指向待删节点的前1节点
            node->next->prev = node->prev;

            free(node);    //释放内存
            head->data--;  //有效节点数-1
            return 1;
        }
        //继续往下找
        node = node->next;
    }
    return 0;//删除失败

}

//链表的遍历
void list_print(list *head)
{
    list *node = head->next;  //第1个有效节点

    while(node != head)
    {
        printf("%d->",node->data);
        node = node->next;
    }
    printf("NULL\n");
}          

运行结果:
在这里插入图片描述
代码分析:

  1. 头插法
    1). 链表为空时
    在这里插入图片描述
new->prev = head;//1.新节点的前驱指针指向头节点
new->next = head;//2.新节点的后继指针指向头节点
head->prev = new;//3.头节点的前驱指针指向新节点
head->next = new;//4.头节点的后继指针指向新节点

2). 链表不为空时
在这里插入图片描述

new->prev = head;      //1.新节点的前驱指针指向头节点
new->next = head->next;//2.新节点的后继指针指向第1个有效节点
head->next = new;       //3.头节点的后继指针指向新节点
head->next->prev = new; //4.第1个有效节点的前驱指针指向新节点
  1. 尾插法
    在这里插入图片描述
new->prev = tail;//1.新节点的前驱指针指向尾节点
new->next = head;//2.新节点的后继指针指向头节点
head->prev = new;//3.头节点的前驱指针指向新节点
tail->next = new;//4.尾节点的后继指针指向新节点
  1. 链表的删除
    (待删节点是否为尾节点的情况一样)
    在这里插入图片描述
//待删节点的前1节点的后继指针指向待删节点的后1节点
node->prev->next = node->next;
//待删节点的后1节点的前驱指针指向待删节点的前1节点
node->next->prev = node->prev;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

⁽⁽ଘ晴空万里ଓ⁾⁾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值