带头双向循环链表基础知识归纳

 本节博主将归纳带头双向循环链表的初始化,头尾插和头尾删

首先让我们一起瞅瞅这链表长啥样:

205db3a1f17d3207f412ae9253017e5b.png

(图像来源:图解几种常见的线性表 - 命中水 (cxiansheng.cn))

在这张图中我们能够得出一个双向循环链表所需要的结构体基本框架:

struct node

{

        int data;//装的数据,我们这里默认int类型

        struct node*prev;//指向前一个节点

        struct node*next;//指向后一个节点
};

一. 初始化

函数声明:void init(struct node **head);

创建思路:

1.因为是双向链表所以无疑head是指针类型,那在函数声明时就需要用到二重指针

2.初始化时需要给head开辟动态内存空间

3.head内部的prev和next需要指向head本身,如图所示:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCx6KaBIOWuheWcqOWutg==,size_20,color_FFFFFF,t_70,g_se,x_16

 写成代码就是:

(*head)->next=*head;

(*head)->prev=*head;

下面我们就能一起创建初始化函数了!

void init(struct node**head)
{
    *head=(struct node*)malloc(sizeof(struct node);
    (*head)->data=0;
    (*head)->prev=(*head)->next=*head;
}

PS:所有链表均未进行动态分配成功与否判断,可自行添加,本节不再编写

二. 头插法

函数声明:void pushfront(struct node**head);

创建思路:

1.创建并初始化新节点(可以另写创建节点函数,本次不在讲解,可自行看代码体会)

2.保存原头节点的next(有实值的第一个节点),并使该节点的prev指向新节点

    新节点的next指向该节点(可以说是双向奔赴😏)

3.使head的next指向新节点,新节点prev指向head(双向奔赴)

4.注意:2和3的顺序不能调换,后果是会丢失实值第一个节点!

看看代码:

void pushfront(struct node**head)
{
    struct node *newnode=(struct node*)malloc(sizeof(struct node);
    newnode->data=1;//可以自定义,也可以编写专门的创建新节点的函数
    newnode->next=(*head)->next;
    (*head)->next->prev=newnode;
    (*head)->next=newnode;
    newnode->prev=*head;//注意先后顺序!
}

三.头删法

函数声明:void popfront(struct node**head);

创建思路:

1.找到实值第二个节点(简称secnode)并保存

2.head的next指向secnode

3.free掉scenode的prev即实值第一个节点

4.secnode的prev指向head

代码献上:

void popfront(struct node**head)
{
    (*head)->next=(*head)->next->next;
    free((*head)->next->prev);
    (*head)->next->prev=*head;
}

四.尾插法

函数声明:void pushback(struct node**head);

创建思路:

1.创建并初始化新节点

2.保存head的prev节点(所谓的尾节点)

3.尾节点的next指向新节点,新节点的prev指向尾节点

4.新节点的next指向head,head的prev指向新节点

代🦓:

void pushback(struct node**head)
{
    struct node *newnode=(struct node*)malloc(sizeof(struct node);
    newnode->data=1;//可以自定义,也可以编写专门的创建新节点的函数
    (*head)->prev->next=newnode;
    newnode->prev=(*head)->prev;
    newnode->next=*head;
    (*head)->prev=newnode;
}

五.尾删法

函数声明:void popback(struct node**head);

创建思路:

1.head的prev指向secbacknode((*head)->prev->prev)

2.free掉尾节点

3.secbacknode的next指向head

代码:

void popback(struct node**head)
{
    (*head)->prev=(*head)->prev->prev;
    free((*head)->prev->next);
    (*head)->prev->next=*head;
}

 

小结:无论是头插头删还是尾插尾删,均请注意编写顺序哦~


       未完待续,有时间接着做,求求三连😗

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

就要 宅在家

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

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

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

打赏作者

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

抵扣说明:

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

余额充值