Java数据结构--双向链表

在上一篇中我们学习了单向链表的实现,链表中我们除了单向链表还有双向链表,在这一篇我们将更进一步地了解链表,实现双向链表

一:认识双向链表

1.双向链表的结构

双向链表是一种可以双向遍历的链表,它的指针可以指向前后两个方向的节点。双向链表拥有头节点和尾节点,可以从头节点进入链表进行操作,同时也可以从尾节点进入链表进行操作,下图便为双向链表的结构

e8fa7712302843078525ebf42475a774.jpg

2.与单向链表的区别

与单链表不同的是,双向链表拥有两个指针prev(前一个节点)和next(下一个节点),比单链表多了一个指向前一节点的引用地址。双向链表的优点是,在操作链表中的上一节点时可以通过前指针直接向前遍历,而无需从头节点开始重新遍历,提高了链表的效率。其缺点是比单链表结构多了一个指针地址,会占用更多的内存来进行存储。

二:代码实现(要先了解泛型)

双链表看着复杂,不好理解,但它本质与单链表一样,方法的实现也与单链表基本相同,因此我们不需害怕,下面我会带你们一起实现,当你们看完就会说:哦!这什么丫?这么简单,这不跟单链表一样吗?

1.节点的创建

54ceede160bf4d2e813053c8ab56f9e1.jpg

根据每一个节点,我们知道每个节点都拥有prev指针(指向前一个节点)和next指针 (指向后一个节点),因此我们的节点对象要包含val值,以及两个指针

ca20c68e70fd4b148f2b9448d0e0bf9d.png

2.链表结构的创建

双向链表拥有头节点和尾节点,它比单链表多了一个尾节点,在构造方法中我们需要注意的是,在初始化头尾节点时,我们要先创建节点,将它的val以及两个指针都赋值为null,然后再去更新头尾指针

若在创建中直接将head的指针指向tail,那head的next指针就会永为null,在后面的方法的书写中再去更新heed的指针就会报错(我第一次这样写,找这个bug找了一个小时\(`Δ’)/)

49e6b6cbd40642dfa148806378ba3dec.jpg

3.增删改查的方法实现

下面我们将实现双向链表中一些常用的方法,它们几乎与单链表一致

①add 在链表中添加元素

add方法有三种情况: addFirst(值) 在首部添加元素

add(值) 在尾部添加元素

add(值,索引) 在指定位置添加元素

这里我们先从第三种情况开始考虑

要知道,插入一个节点,我们要将新节点的指针更新,再将它指定位置的前一个节点的next指针以及指定位置的节点的prev指针断开,因此我们寻找位置时也要需要找到要插入位置的前一个节点

01cebc90d1d64b488ee29cfa672c7128.jpg

思路:我们首先创建一个新节点来储存val值,再定义一个下标i来寻找要插入的位置,找到位置后,更新新节点指针以及新节点前后节点的指针

6ac7a9ce64fc4a8ebed845d2f83e255e.jpg

这里我们再考虑其他两种边界情况

Ⅰ.addFirst 在首部添加元素

此时p即为head,n即为head的下一个节点,就是在0索引位置添加元素

Ⅱ.add 在尾部添加元素

此时p为tail的前一个节点,n为tail节点,就是在链表长度size位置添加元素

以上两种均为情况三的一种,因此我们就可以直接引用,从而简化代码

②get(索引) 获取指定位置元素

思路:定义一个下标i用来寻找位置,其实相当于数组的遍历,但我们可以从头节点位置开始寻找,也可以从尾节点位置开始寻找,这里我们从头节点开始

5e855e2991244f878f0c28bb50d7dffe.jpg

 ③remove(索引) 删除指定位置的元素

9898f76fcbb74e5b963e0d90f98023b5.png

 删除节点也存在三种情况

情况一:链表为空链表

情况二:要删除的节点处于尾节点位置

以上两种均为边界情况

情况三:要删除的节点不处于边界

我们先从情况三开始分析

思路:我们需要知道要删除节点的上一个节点以及下一个节点,再去更新指针

bac6e8cbaffa424197267636335150ee.jpg

8bcd616441ef4ef58bf5d1825292bb13.png

接下来我们来思考其他两种边界情况

Ⅰ.当链表为空时,我们直接抛出异常即可,不必再走循环

Ⅱ.当我们要删除的节点位于尾节点

尾节点是不能删除的

a87f6262eecf4fe4964bad14372c6538.jpg

根据我们情况三的代码 ,此时p为An,n为null,null没有指针,那么这种情况不考虑的话程序就会报错,因此对于这种情况我们也要考虑

思路:若要删除的节点位于尾节点,直接抛出异常

4.结果显示

写完代码后,是不是感觉这双向链表与单向链表几乎一样啊,下面我们来带入数据爽一下吧

9e4be6ed88224ac986ad91be62452e33.png

db3909f695e644d28241678460f9f6fd.png 

各位都实现了吗?

注:若存在错误,不足之处,望各位指出更正₍˄·͈༝·͈˄*₎◞ ̑̑

 

 

 

 

 

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

汤姆大聪明

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

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

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

打赏作者

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

抵扣说明:

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

余额充值