JAVA初阶数据结构链表(2)双向链表( +专栏数据结构练习是完整版)

1.双向链表的结构(双向不带头不循环链表)

需要注意的一点就是,在jdk中的链表就是双向链表

一个节点有三个域 val(数值域) next(地址域) prev(前驱记录前一个节点的地址)

在双向链表中我们还定义了一个last用来标记最后一个节点

2.双向链表的具体实现

1.定义一个MyLinkedLIst的类(它要实现的所有内容是和单向链表中接口的方法是一样的)

双向链表的实现的方法和单项链表的方法是一样的所以接入的接口也是一样的

在写这些方法之前要先定义一个双向链表的基本框架其中构造方法是为了能够链表传入val的参数

2.1双向链表中display方法(打印链表)方法的实现 

双向链表的打印和单项链表是一样的,因为都是头节点cur从头走到尾。

2.2双向链表size方法(打印链表长度是多少)的方法的实现

也和单向链表是一样的,都是头结点从头走到尾

2.3双向链表contains(找寻专门的元素在链表中对的位置)的方法的实现

基本框架

 代码实现

 2.3双向链表addFirst方法

不进行详细讲解,绿色字看不动到专栏链表一中进行查看;

要注意的是要是只有一个节点的化就不能这样写,会发生空指针异常,所以一个的时候我们只需要让头结点指向它,然后last也指向node就行了。

2.4双向两步addlast方法(插入一个元素到节点的最后一个)

和头插法是相似的

2.5双向链表在指定位置来对要插入的数值进行插入 

和单向链表不同的是双向链表可以前进和后退 

所以我们只需要走到要插入的节点的位置,然后修改四个指向就可以了

先连后面再连前面

分两种情况如果在头部就直接插入,如果不在头部就正常进行插入,如果在尾部那么就直接尾插法,循环条件大家看一下没啥问题我相信大家的能力 

2.6删除方法remove()删除一个元素指定的

del是要删除节点的位置

其中我们要注意两种情况

要是写错的化会有空指针异常,因为headA和last存的地址的值是null所以会报错

所以我们要避免这种情况

下面是详细的图解(用删除中间节点的逻辑来对其进行删除)

(1)删除头节点的思路

       将headA往后面移动一个,然后将headA的prev位置重置为空

       也就是

      headA = headA.next;

       head.prev = null 

(2)删除中间节点的思路

(3)删除最后节点的思路

总体代码实现 

这个代码还有一个问题(隐型的问题) 如果只删除一个节点那么就会让head为null发生空指针异常,所以我们要防止这种情况

总体代码太长了不能图片

 public void remove(int key) {
        ListNode cur = head;
        while (cur != null) {
            if(cur.val == key) {
                if(cur == head) {
                    head = head.next;
                    if(head != null) {
                        head.prev = null;
                    }else {
                        //只有一个节点 且是需要删除的节点
                        last = null;
                    }
                }else {
                    cur.prev.next = cur.next;
                    //删除中间节点
                    if(cur.next != null) {
                        cur.next.prev = cur.prev;
                        //cur.prev.next = cur.next;
                    }else {
                        //删除尾巴节点
                        //cur.prev.next = cur.next;
                        last = last.prev;
                    }
                }
                return;
            }
            cur = cur.next;
        }
    }

2.7删除方法removeall()删除所有这个指定元素的值

这个方法和remove方法可以说是一毛一样

在remove方法中我们不是return结束这个循环了吗,我们只要不结束这个循环让他继续走那么就可以继续进入循环进行删除

所以我们可以这样

这样就完成了

整体代码

public void removeAllKey(int key) {
        ListNode cur = head;
        while (cur != null) {
            if(cur.val == key) {
                if(cur == head) {
                    head = head.next;
                    if(head != null) {
                        head.prev = null;
                    }else {
                        //只有一个节点 且是需要删除的节点
                        last = null;
                    }
                }else {
                    cur.prev.next = cur.next;
                    //删除中间节点
                    if(cur.next != null) {
                        cur.next.prev = cur.prev;
                        //cur.prev.next = cur.next;
                    }else {
                        //删除尾巴节点
                        //cur.prev.next = cur.next;
                        last = last.prev;
                    }
                }
            }
            cur = cur.next;
        }
    }

2.8clear方法删除所有的元素

让头结点和last节点都为空就直接清除了

后面我会在java进阶课程中详细讲解他的清空过程

进入clear的源码

其实和我写的差不多

io流那里估计是

最后希望大家看完这链表两个数据结构的文章以后就去看源码我写的和源码其实差不多,只不过源码的封装更多

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Frank1-0-2-4

我会继续努力的,十分感谢谢谢你

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

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

打赏作者

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

抵扣说明:

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

余额充值