【一起学数据结构与算法】Java实现双链表

这篇具有很好参考价值的文章主要介绍了【一起学数据结构与算法】Java实现双链表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、双链表的概念

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。

二、双链表一些方法的实现

2.1 双链表的属性

class ListNode {
    public int val;
    public ListNode prev;
    public ListNode next;

    public ListNode(int val) {
        this.val = val;
    }
}
public class MyLinkedList {

    public ListNode head;//指向双向链表的头节点
    public ListNode last;//指向的是尾巴结点
    }

2.2 打印双链表

打印双链表非常简单,只需要单独创一个结点cur来遍历链表并打印

//打印双向链表
public void display() {
        //和单链表的打印方式是一样的
        ListNode cur = this.head;
        while (cur != null) {
            System.out.print(cur.val + " ");
            cur = cur.next;
        }
        System.out.println();
    }

2.3 得到双链表的长度

单独创一个结点cur来遍历链表同时创一个count计数器来计算长度即可

//得到双链表的长度
    public int size() {
        ListNode cur = this.head;
        int count = 0;
        while (cur != null) {
            count++;
            cur = cur.next;
        }
        return count;
    }

2.4 查找是否包含关键字key是否在双链表中

单独创一个结点cur来遍历链表并且判断是否包含key

//查找是否包含关键字key是否在双链表中
    public boolean contains(int key) {
        ListNode cur = this.head;
        while (cur != null) {
            if (cur.val == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

2.5 头插法

当我们想把新的结点插入到第一个结点位置处,可以先建立一个结点,然后把头结点的prev变为我们新建立结点的next值,然后将我们新建立的结点值变为null,最后将头结点指向新的插入的结点。
注意我们需要首先判断这个链表是否为空,假如为空就直接构建链表即可

//头插法
    public void addFirst(int data) {
        ListNode node = new ListNode(data);
        if (this.head == null) {
            this.head = node;
            this.last = node;
        } else {
            node.next = this.head;
            head.prev = node;
            this.head = node;
        }
    }

2.6 尾插法

尾插法顾名思义就是从结尾插入新的结点,这个和头插法过程差不多,只不过一个是改变head的位置,一个是改变last的位置。
和头插法一样,这个同样需要判断链表是否初始为空

//尾插法
    public void addLast(int data) {
        ListNode node = new ListNode(data);
        if (this.head == null) {
            this.head = node;
            this.last = node;
        } else {
            this.last.next = node;
            node.prev = this.last;
            this.last = node;
        }
    }

2.7 任意位置插入,第一个数据结点为0号下标

首先要考虑,插入的位置是头部或尾部或中间。根据具体的位置实现具体的操作。
如果是头部,直接调用头插,如果是尾部,就直接调用尾插即可。

如果是中间插的的话:

java双链表,一起学数据结构与算法系列,java,链表,数据结构
1.node.next = cur.prev.next;
2.cur.prev.next = node;
3.node.prev = cur.prev;
4.cur.prev = node;
java双链表,一起学数据结构与算法系列,java,链表,数据结构

public ListNode searchIndex(int index) {
        ListNode cur = this.head;
        while (index != 0) {
            cur = cur.next;
            index--;
        }
        return cur;
    }
    //任意位置插入,第一个数据结点为0号下标
    public void addIndex(int index, int data) {
        ListNode node = new ListNode(data);
        if (index < 0 || index >size()) {
            System.out.println("index位置不合法!");
            return;
        }
        if (index == 0) {
            addFirst(data);
            return;
        }
        if (index == size()) {
            addLast(data);
            return;
        }
        ListNode cur = searchIndex(index);
        node.next = cur.prev.next;
        cur.prev.next = node;
        node.prev = cur.prev;
        cur.prev = node;
    }

2.8 删除第一次出现为key的结点

假如是头结点的话我们还需要判断这个链表是否只有一个结点,如果是那么last指针也会为空,head指针也会为空,否则,我们只移动头指针结点就可以
当删除中间结点的时候我们可以先找到对于位置的结点cur,利用对应位置的cur.prev和cur.next确定附近两个结点,然后进行删除即可,这个删除与链表相似,只是多了一个删除头结点而已。

//删除第一次出现为key的结点
    public void remove(int key) {
        ListNode cur = this.head;

        while (cur != null) {
            if (cur.val == key) {
                if (cur == head) {
                    this.head = this.head.next;
                    if (this.head != null) {
                        this.head.prev = null;
                    } else {
                        this.last = null;
                    }
                } else {
                    cur.prev.next = cur.next;
                    if (cur.next != null) {
                        cur.next.prev = cur.prev;
                    } else {
                        this.last = this.last.prev;
                    }
                }
                return;
            }
            cur = cur.next;
        }
    }

2.9 删除所有key的值

//删除所有key的值
    public void removeAllKey(int key) {
        ListNode cur = this.head;

        while (cur != null) {
            if (cur.val == key) {
                if (cur == head) {
                    this.head = this.head.next;
                    if (this.head != null) {
                        this.head.prev = null;
                    } else {
                        this.last = null;
                    }
                } else {
                    cur.prev.next = cur.next;
                    if (cur.next != null) {
                        cur.next.prev = cur.prev;
                    } else {
                        this.last = this.last.prev;
                    }
                }
            }
            cur = cur.next;
        }
    }

2.10 清空双链表

//清空双链表
    public void clear() {
        while (this.head != null) {
            ListNode curNext = head.next;
            this.head.next = null;
            this.head.prev = null;
            this.head = curNext;
        }
        last = null;
    }

三、MyLinkedList.java


class ListNode {
    public int val;
    public ListNode prev;
    public ListNode next;

    public ListNode(int val) {
        this.val = val;
    }
}

public class MyLinkedList {

    public ListNode head;//指向双向链表的头节点
    public ListNode last;//指向的是尾巴结点


    //打印双向链表
    public void display() {
        //和单链表的打印方式是一样的
        ListNode cur = this.head;
        while (cur != null) {
            System.out.print(cur.val + " ");
            cur = cur.next;
        }
        System.out.println();
    }

    //得到双链表的长度
    public int size() {
        ListNode cur = this.head;
        int count = 0;
        while (cur != null) {
            count++;
            cur = cur.next;
        }
        return count;
    }

    //查找是否包含关键字key是否在双链表中
    public boolean contains(int key) {
        ListNode cur = this.head;
        while (cur != null) {
            if (cur.val == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

    //头插法
    public void addFirst(int data) {
        ListNode node = new ListNode(data);
        if (this.head == null) {
            this.head = node;
            this.last = node;
        } else {
            node.next = this.head;
            head.prev = node;
            this.head = node;
        }
    }

    //尾插法
    public void addLast(int data) {
        ListNode node = new ListNode(data);
        if (this.head == null) {
            this.head = node;
            this.last = node;
        } else {
            this.last.next = node;
            node.prev = this.last;
            this.last = node;
        }
    }


    public ListNode searchIndex(int index) {
        ListNode cur = this.head;
        while (index != 0) {
            cur = cur.next;
            index--;
        }
        return cur;
    }
    //任意位置插入,第一个数据结点为0号下标
    public void addIndex(int index, int data) {
        ListNode node = new ListNode(data);
        if (index < 0 || index >size()) {
            System.out.println("index位置不合法!");
            return;
        }
        if (index == 0) {
            addFirst(data);
            return;
        }
        if (index == size()) {
            addLast(data);
            return;
        }
        ListNode cur = searchIndex(index);
        node.next = cur.prev.next;
        cur.prev.next = node;
        node.prev = cur.prev;
        cur.prev = node;
    }

    //删除第一次出现为key的结点
    public void remove(int key) {
        ListNode cur = this.head;

        while (cur != null) {
            if (cur.val == key) {
                if (cur == head) {
                    this.head = this.head.next;
                    if (this.head != null) {
                        this.head.prev = null;
                    } else {
                        this.last = null;
                    }
                } else {
                    cur.prev.next = cur.next;
                    if (cur.next != null) {
                        cur.next.prev = cur.prev;
                    } else {
                        this.last = this.last.prev;
                    }
                }
                return;
            }
            cur = cur.next;
        }
    }

    //删除所有key的值
    public void removeAllKey(int key) {
        ListNode cur = this.head;

        while (cur != null) {
            if (cur.val == key) {
                if (cur == head) {
                    this.head = this.head.next;
                    if (this.head != null) {
                        this.head.prev = null;
                    } else {
                        this.last = null;
                    }
                } else {
                    cur.prev.next = cur.next;
                    if (cur.next != null) {
                        cur.next.prev = cur.prev;
                    } else {
                        this.last = this.last.prev;
                    }
                }
            }
            cur = cur.next;
        }
    }

    //清空双链表
    public void clear() {
        while (this.head != null) {
            ListNode curNext = head.next;
            this.head.next = null;
            this.head.prev = null;
            this.head = curNext;
        }
        last = null;
    }
}

四、Test.java


public class Test {
    public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.addFirst(1);
        myLinkedList.addFirst(2);
        myLinkedList.addFirst(3);
        myLinkedList.addFirst(4);
        System.out.println(myLinkedList.size());
        myLinkedList.display();
        System.out.println(myLinkedList.contains(1));
        myLinkedList.addLast(1);
        myLinkedList.addLast(2);
        myLinkedList.addLast(3);
        myLinkedList.addLast(4);
        myLinkedList.display();
        myLinkedList.remove(1);
        myLinkedList.display();
        myLinkedList.removeAllKey(4);
        myLinkedList.display();
        myLinkedList.addIndex(0,99);
        myLinkedList.display();
        myLinkedList.clear();
        myLinkedList.display();

    }
}

五、效果展示

java双链表,一起学数据结构与算法系列,java,链表,数据结构文章来源地址https://www.toymoban.com/news/detail-834811.html

到了这里,关于【一起学数据结构与算法】Java实现双链表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 双链表——“数据结构与算法”

    各位CSDN的uu们你们好呀,今天,小雅兰又回来了,到了好久没有更新的数据结构与算法专栏,最近确实发现自己有很多不足,需要学习的内容也有很多,所以之后更新文章可能不会像之前那种一天一篇或者一天两篇啦,话不多说,下面,让我们进入双链表的世界吧  之前小雅

    2024年02月04日
    浏览(38)
  • 【一起学数据结构与算法】快速教你了解并实现单链表

    此篇是对单链表知识的学习和实现,基本上大体的方法实现和思路都已经表达,如果有不对的地方,还请各位大佬多多指教! 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素

    2024年02月19日
    浏览(43)
  • 【数据结构】数组、双链表代码实现

    💗💗💗欢迎来到我的博客,你将找到有关如何使用技术解决问题的文章,也会找到某个技术的学习路线。无论你是何种职业,我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章,也欢迎在文章下方留下你的评论和反馈。我期待着与你分享知识、互

    2024年02月19日
    浏览(45)
  • 【数据结构】单链表 && 双链表(链式和数组实现)

           🔥🔥 欢迎来到小林的博客!!       🛰️博客主页:✈️小林爱敲代码       🛰️博客专栏:✈️ 数据结构与算法       🛰️社区 :✈️ 进步学堂       🛰️欢迎关注:👍点赞🙌收藏✍️留言 今天给大家带来四个内容,一个

    2024年02月01日
    浏览(55)
  • 【数据结构】链表(单链表与双链表实现+原理+源码)

    博主介绍:✌全网粉丝喜爱+、前后端领域优质创作者、本质互联网精神、坚持优质作品共享、掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战✌有需要可以联系作者我哦! 🍅附上相关C语言版源码讲解🍅 👇🏻 精彩专栏推荐订阅👇🏻 不然下次找

    2024年01月24日
    浏览(143)
  • 【数据结构与算法】顺序表与链表(单链表和双链表)超详解图示与源码。

                                                       大家好,今天我们来学习数据结构中的顺序表与链表!源码在最后附上 首先我们先来认识一下 顺序表 :                                       **如上图所示:很多人会以为数组就是顺序表,顺序表就是数组,这

    2024年02月21日
    浏览(60)
  • [C语言][数据结构][链表] 双链表的从零实现!

    目录 零.必备知识 0.1 一级指针 二级指针 0.2 双链表节点的成员列表         a. 数据         b. 后驱指针         c. 前驱指针 0.3 动态内存空间的开辟 一. 双链表的实现与销毁         1.1 节点的定义         1.2 双向链表的初始化 创建新节点         1.3 尾插       

    2024年04月17日
    浏览(244)
  • 【数据结构】C语言实现双链表的基本操作

    大家好,很高兴又和大家见面啦!!! 经过前面几个篇章的内容分享,相信大家对顺序表和单链表的基本操作都已经熟练掌握了。今天咱们将继续分享线性表的链式存储的第二种形式——双链表。在今天的内容中,咱们将介绍双链表的创建以及一些基本操作,接下来跟我一起

    2024年02月04日
    浏览(62)
  • 【一起学习数据结构与算法】优先级队列(堆)

    如果我们给每个元素都分配一个数字来标记其优先级,不妨设较小的数字具有较高的优先级,这样我们就可以在一个集合中访问优先级最高的元素并对其进行查找和删除操作了。这样,我们就引入了 优先级队列 这种数据结构。 优先级队列(priority queue) 是0个或多个元素的集

    2024年01月19日
    浏览(42)
  • 一起学数据结构(12)——归并排序的实现

    归并排序的大概原理如下图所示:         从图中可以看出,归并排序的整体思路就是把已给数组不断分成左右两个区间,当这个区间中的数据数量到达一定数值时,便返回去进行排序,整体的结构类似二叉树的结构,因此,对于归并排序同样可以利用递归进行实现。    

    2024年02月08日
    浏览(40)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包