双向链表详解

这篇具有很好参考价值的文章主要介绍了双向链表详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一,双向链表的概念及结构 

二,双向链表的方法及其实现

2.1 双向链表

2.2 addFirst(int data) - 头插法 

2.3 addLast(int data) - 尾插法

2.4 size() - 链表长度

2.5 display() - 打印链表内容

2.6 clear() - 删除链表

2.7 addIndex(int index, int data) - 任意位置插入

2.8 contains(int key) - 链表当中是否有key

2.9 remove(int key) - 删除链表中第一次出现的key

2.10 removeAllKey(int key) - 删除所有值为key的节点


一,双向链表的概念及结构 

与单向链表相同,只不过每一个节点中多了一个空间来存储上一个节点的地址,结构如下图所示:

双向链表,链表,数据结构,java,算法

二,双向链表的方法及其实现

2.1 双向链表

链表类的定义及我们接下来要实现的方法,如下代码:

public class LinkedList {
    static class ListNode{//节点类 - 因为节点是链表的属性,所以用static来修饰
        //节点的成员
        public int val;
        public ListNode prev;
        public ListNode next;
        public ListNode(int val){
            this.val = val;
        }
    }
    public ListNode head;//头节点 - 不是每个节点都是头节点,它是链表的属性,所以定义在节点类外面
    public ListNode last;//尾节点 - 同头节点

    //头插法
    public void addFirst(int data){}

    //尾插法
    public void addLast(int data){}

    //在任意位置插入,假设第一个节点的下标为0
    public void addIndex(int index, int data){}

    //查找是否包含关键字key是否在单链表当中
    public boolean contains(int key){}

    //删除第一次出现关键字为key的节点
    public void remove(int key){}

    //删除所有值为key的节点
    public void removeAllKey(int key){}

    //得到单链表的长度
    public int size(){}

    //打印链表内容
    public void display(){}

    //删除链表
    public void clear(){}
}

2.2 addFirst(int data) - 头插法 

顾名思义,就是在头节点之前插入一个节点,并将其变成头节点。 如图

双向链表,链表,数据结构,java,算法

但是我们还要注意如果链表当中没有元素的情况,如图:

双向链表,链表,数据结构,java,算法

    public void addFirst(int data){
        ListNode node = new ListNode(data);//创建一个节点
        if(head == null){//无元素的情况
            head = node;
            last = node;
            return;
        }
        head.prev = node;//1
        node.next = head;//2
        head = node;//4
    }

2.3 addLast(int data) - 尾插法

双向链表,链表,数据结构,java,算法

 但是我们还要注意如果链表当中没有元素的情况,如图:

双向链表,链表,数据结构,java,算法

    public void addLast(int data){
        ListNode node = new ListNode(data);
        if(head == null){
            head = node;
            last = node;
            return;
        }
        last.next = node;
        node.prev = last;
        last = node;
    }

2.4 size() - 链表长度

遍历链表

    public int size(){
        ListNode cur = head;//不能直接用head遍历,会改变head节点
        int count = 0;
        while(cur != null){
            cur = cur.next;
            count++;
        }
        return count;
    }

2.5 display() - 打印链表内容

遍历链表

    public void display(){
        ListNode cur = head;
        while(cur != null){
            System.out.print(cur.val + " ");
            cur = cur.next;
        }
        System.out.println();//换行
    }

2.6 clear() - 删除链表

遍历链表 - 将所有值置为空

    public void clear(){
        ListNode cur = head;        
        while (cur != null) {
            ListNode curNext = cur.next;
            cur.prev = null;
            cur.next = null;
            cur = curNext;
        }
        head = null;
        last = null;
    }

2.7 addIndex(int index, int data) - 任意位置插入

1.  要先判断他输入的下标合不合法

2.  看下标是不是头节点,尾节点,是的话直接调用头插法,尾插法

3.  如图

双向链表,链表,数据结构,java,算法

   public void addIndex(int index,int data){
        if(index < 0 || index > size()) {
            System.out.println("index不合法!");
            return;
        }
        if(index == 0) {
            addFirst(data);
            return;
        }
        if(index == size()) {
            addLast(data);
            return;
        }
        //cur拿到了index下标的节点的地址
        ListNode cur = head;
        while (index != 0) {
            cur = cur.next;
            index--;
        }
        ListNode node = new ListNode(data);
        node.prev = cur.prev;
        node.next = cur;
        cur.prev.next = node;
        cur.prev = node;
    }

2.8 contains(int key) - 链表当中是否有key

遍历链表

      public boolean contains(int key){
        ListNode cur = head;
        while (cur != null){
            if(cur.val == key){
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

2.9 remove(int key) - 删除链表中第一次出现的key

1. 先找到key所在的位置

2. 判断是不是头节点,如果是且不只有一个元素 

双向链表,链表,数据结构,java,算法

如果是头节点且只有一个头节点:

双向链表,链表,数据结构,java,算法

3. 再判断是不是尾节点,如果是:

双向链表,链表,数据结构,java,算法

4.是中间节点,如图:

双向链表,链表,数据结构,java,算法

 

    public void remove(int key){
        ListNode cur = head;
        while(cur != null){
            if(cur.val == key){
                if(cur == head){
                    head = head.next;
                    if(head == null){//只有一个元素
                        last = null;
                    }else {//有多个元素
                        head.prev = null;
                    }
                }else {
                    if(cur == last){//尾节点
                        last = last.prev;
                        last.next = null;
                    }else {//中间节点
                        cur.prev.next = cur.next;
                        cur.next.prev = cur.prev;
                    }
                }
                return;
            }
            cur = cur.next;
        }
    }

2.10 removeAllKey(int key) - 删除所有值为key的节点

与remove方法相同,只不过删除成功后不要return,继续往后遍历:文章来源地址https://www.toymoban.com/news/detail-733921.html

    public void removeAllKey(int key){
        ListNode cur = head;
        while(cur != null){
            if(cur.val == key){
                if(cur == head){
                    head = head.next;
                    if(head == null){
                        last = null;
                    }else {
                        head.prev = null;
                    }
                }else {
                    if(cur == last){//尾节点
                        last = last.prev;
                        last.next = null;
                    }else {
                        cur.prev.next = cur.next;
                        cur.next.prev = cur.prev;
                    }
                }
                //return这里不同
            }
            cur = cur.next;
        }
    }

到了这里,关于双向链表详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构与算法(四):双向链表

    双向链表概念和单向链表是一致的,区别在于双向链表在单向链表的基础上,指针区域多了一个指向上一个节点的指针。单向链表内容可以参考我的上一篇文章:http://t.csdn.cn/Iu56H。 基本的数据结构如图所示: 双向链表结构包含了节点的数据内容和两个指针:指向前一个节点

    2024年02月14日
    浏览(52)
  • 【数据结构】动图详解双向链表

    目录 1.单向链表的劣势 2.带头双向循环链表         1.逻辑结构        2.结点的代码实现 3.双向链表接口的实现         1.接口1---初始化         2.接口2,3---头插,尾插         3. 接口4,5---头删,尾删         3. 接口6---查找          4. 接口7,8--插入,

    2024年01月23日
    浏览(60)
  • 数据结构之双向链表详解

    😽博主CSDN主页:小源_😽 🖋️个人专栏:《数据结构》🖋️ 😀努力追逐大佬们的步伐~ 上一篇文章中我们重点讲解了无头单向非循环链表的模拟实现,现在我们来讲解LinkedList(无头双向链表实现 )的模拟实现。 本章重点: 本文着重讲解了LinkedList(无头双向单链表)的实现

    2024年02月04日
    浏览(54)
  • 数据结构学习分享之双向链表详解

        💓博主CSDN:杭电码农-NEO💓🎉🎉🎉       ⏩专栏分类:数据结构学习分享(持续更新中🫵)⏪🎉🎉🎉       我们上一期说到,两链表中有两个最常用的结构,一个是最简单的无头不循环单向链表,还有一个就是 结构相对比较复杂的带头双向循环链表 ,我们这一章节就来

    2024年02月04日
    浏览(68)
  • 【数据结构和算法】使用数组的结构实现链表(单向或双向)

    上文我们通过结构体的结构实现了队列 、以及循环队列的实现,我们或许在其他老师的教学中,只学到了用结构体的形式来实现链表、队列、栈等数据结构,本文我想告诉你的是,我们 可以使用数组的结构实现链表、单调栈、单调队列 目录 前言 一、用数组结构的好处 1.数

    2024年01月20日
    浏览(74)
  • 【数据结构与算法】之双向链表及其实现!

    ​                                                                                 个人主页:秋风起,再归来~                                                                                             数据结构与

    2024年04月23日
    浏览(42)
  • 数据结构 - 链表详解(二)—— 带头双向循环链表

    链表的结构一共有 八种 :带头单向循环链表、带头单向非循环链表、带头双向循环链表、带头双向非循环链表、无头单向循环链表、无头单向非循环链表、无头双向循环链表、无头双向非循环链表。 今天我们来详解带头双向循环链表 带头双向循环链表是一种数据结构,它通

    2024年04月26日
    浏览(57)
  • 【数据结构与算法】 - 双向链表 - 详细实现思路及代码

    前几篇文章介绍了怎样去实现单链表、单循环链表, 这篇文章主要介绍 双向链表 以及实现双向链表的步骤,最后提供我自己根据理解实现双向链表的C语言代码 。跟着后面实现思路看下去,应该可以看懂代码,看懂代码后,就对双向链表有了比较抽象的理解了,最后自己再

    2024年02月01日
    浏览(39)
  • 数据结构:线性表之-循环双向链表(万字详解)

    目录 基本概念 1,什么是双向链表 2,与单向链表的区别 双向链表详解 功能展示: 1. 定义链表 2,创建双向链表 3,初始化链表 4,尾插 5,头插 6,尾删 判断链表是否被删空 尾删代码 7,头删 8,pos位置之前插入 优化后的头插 优化后的尾插 9,删除pos位置的节点 优化后的尾删 优

    2024年02月09日
    浏览(51)
  • 【数据结构和算法】实现带头双向循环链表(最复杂的链表)

    前文,我们实现了认识了链表这一结构,并实现了无头单向非循环链表,接下来我们实现另一种常用的链表结构,带头双向循环链表。如有仍不了解单向链表的,请看这一篇文章(7条消息) 【数据结构和算法】认识线性表中的链表,并实现单向链表_小王学代码的博客-CSDN博客

    2024年01月17日
    浏览(78)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包