【java-数据结构14-双向链表的增删查改2】

   上一篇文章中,我们已经对双向链表进行一些基本操作,本篇文章我们继续通过对链表的增删查改来加深对链表的理解~同时有任何不懂的地方可以在评论区留言讨论,也可以私信小编~觉得小编写的还可以的可以留个关注支持一下~话不多说正片开始~

注意:上篇文章少了一些图,这里做些补充重新发一遍

1.任意位置插入

1.对插入位置进行合法性判断

2.如果等于0即为头插法,等于size即为尾插法

小于0大于saize都是不可以的,代码如下

private void checkIndex(int index) {
        if(index < 0 || index > size()) {
            throw new IndexOutOfException("index 不合法!"+index);
        }
    }

上面我们抛出一个自定义异常 ,也不要忘记定义一个异常类,代码如下

 public class IndexOutOfException extends RuntimeException{
        public IndexOutOfException() {
        }

        public IndexOutOfException(String message) {
            super(message);
        }
    }

3.定义cur,也就是要插入的位置

代码如下

public void addIndex(int index,int data){
        checkIndex(index);
        if(index == 0) {
            addFirst(data);
            return;
        }
        if(index == size()) {
            addLast(data);
            return;
        }
        ListNode cur = searchIndex(index);
        ListNode node = new ListNode(data);
        node.next = cur;
        cur.prev.next = node;
        node.prev = cur.prev;
        cur.prev = node;
    }

调用测试

public class test {
    public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.addFirst(56);
        myLinkedList.addFirst(45);
        myLinkedList.addFirst(34);
        myLinkedList.addFirst(23);
        myLinkedList.addFirst(12);
        myLinkedList.addLast(67);

        myLinkedList.display();
        myLinkedList.addIndex(0,999);
        myLinkedList.display();
     
    }

运行截图 

2.删除第一次出现的key节点

  如果是单链表,我们是需要找到要删除的前一个节点的,让删除的节点被跳过即可

  双链表则不需要那么麻烦,我们先看中间节点,直接找到要删除的节点cur,让cur.prev.next = cur.next; cur.next.prev = cur.prev;即可 如图

接下来我们讨论如果要删除的是头节点 :先让head = head.next并且head.prev = null

注意:那么如果只有一节点呢head = head.nex代码执行完毕后head就为null,那么head.prev = null就会异常,那么我们要加一个前置条件if:head!=null,如果head等于null,手动把last置为空即可

下面我们讨论要删除的是尾巴节点cur.prev.next = cur.next; last = last.prev

代码如下

 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 {
                    //删除中间节点 和  尾巴节点
                    if(cur.next != null) {
                        //删除中间节点
                        cur.prev.next = cur.next;
                        cur.next.prev = cur.prev;
                    }else {
                        //尾巴节点
                        cur.prev.next = cur.next;
                        last = last.prev;
                    }
                }
                return;
            }else {
                cur = cur.next;
            }
        }
    }

调用测试

 public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.addFirst(56);
        myLinkedList.addFirst(45);
        myLinkedList.addFirst(34);
        myLinkedList.addFirst(23);
        myLinkedList.addFirst(12);
        myLinkedList.addLast(67);

        myLinkedList.display();
       myLinkedList.remove(23);
       
        myLinkedList.display();
     


    }

运行截图

 

3.删除所有出现的key节点

    此题逻辑与上题基本相同,只是我们上一个题删除第一个节点后就返回了,我们只要让cur继续往后走即可

代码如下

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 {
                    //删除中间节点 和  尾巴节点
                    if(cur.next != null) {
                        //删除中间节点
                        cur.prev.next = cur.next;
                        cur.next.prev = cur.prev;
                    }else {
                        //尾巴节点
                        cur.prev.next = cur.next;
                        last = last.prev;
                    }
                }
                cur = cur.next;
                //return;
            }else {
                cur = cur.next;
            }
        }
    }

调用测试

 public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.addFirst(56);
        myLinkedList.addFirst(45);
        myLinkedList.addFirst(12);
        myLinkedList.addFirst(12);
        myLinkedList.addFirst(12);
        myLinkedList.addLast(67);

        myLinkedList.display();
        myLinkedList.removeAllKey(12);
     
        myLinkedList.display();
    


    }

运行截图 

4.清空链表

head,last置为null,或者一个一个置null,如图

 

但此时还有head,last两个节点,手动置空即可 

代码如下

 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;
    }

调用测试

 public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        myLinkedList.addFirst(56);
        myLinkedList.addFirst(45);
        myLinkedList.addFirst(12);
        myLinkedList.addFirst(12);
        myLinkedList.addFirst(12);
        myLinkedList.addLast(67);

        myLinkedList.display();
        myLinkedList.clear();
     
        myLinkedList.display();
    

    }

运行截图

5.库中的linkedlist方法使用

 到此为止,我们手动创建链表并对链表进行增删查改就结束的,其实我们还可以通过 库当中的linkedlist,直接使用,下面我们做具体演示

1.导入类:import java.util.List

2.创建链表。

  List<Integer> list1 = new LinkedList<>();

下面是一些方法,这里不做演示了

 

6.LinkedList遍历 

1.for循环

这个方法前面有讲过,这里不多赘述

2.for,each循环

代码如下

 public static void main(String[] args) {
        List<Integer> list = new LinkedList<>();
        list.add(1);
        list.add(1);
        list.add(3);
        for (Integer X:list
             ) {
            System.out.println(X);
        }

    }

运行截图

 

3.迭代器· 

使用迭代器要导入类:import java.util.ListIterator;

代码如下

 public static void main(String[] args) {
        List<Integer> list = new LinkedList<>();
        list.add(1);
        list.add(1);
        list.add(3);
     
        ListIterator<Integer> it = list.listIterator();
        while(it.hasNext()){
            System.out.print(it.next()+ " ");
        }

    }

4.迭代器反向遍历

 

public static void main(String[] args) {
        List<Integer> list = new LinkedList<>();
        list.add(1);
        list.add(1);
        list.add(3);
      
        ListIterator<Integer> rit = list.listIterator(list.size());
        while (rit.hasPrevious()){
            System.out.print(rit.previous() +" ");
        }
        System.out.println();
    }

 

到此为止,我们链表的章节就可以跟大家说在再见了,下一篇文章,我们将会进入栈和队列的学习,觉得小编讲的还可以的可以留个关注~我们下期再见~ 谢谢观看~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/623266.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从头开始学Spring—02基于XML管理bean

目录 1.实验一&#xff1a;入门案例 2.实验二&#xff1a;获取bean 3.实验三&#xff1a;依赖注入之setter注入 4.实验四&#xff1a;依赖注入之构造器注入 5.实验五&#xff1a;特殊值处理 6.实验六&#xff1a;为类类型属性赋值 7.实验七&#xff1a;为数组类型属性赋值…

【Spring Boot】 深入理解Spring Boot拦截器:自定义设计与实现全攻略

&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录文章&#xff1a;【Spring Boot】 深入理解Spring Boot拦截器&#xff1a;自定义设计与实现全攻略 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 SpringBoot统⼀功能处理一…

Go框架三件套:Gorm的基本操作

1.概述 这里的Go框架三件套是指 Web、RPC、ORM框架&#xff0c;具体如下: Gorm框架 gorm框架是一个已经迭代了10年的功能强大的ORM框架&#xff0c;在字节内部被广泛使用并且拥有非常丰富的开源扩展。 Kitex框架 Kitex是字节内部的Golang微服务RPC框架&#xff0c;具有高性能…

初始Django

初始Django 一、Django的历史 ​ Django 是从真实世界的应用中成长起来的&#xff0c;它是由堪萨斯&#xff08;Kansas&#xff09;州 Lawrence 城中的一个网络开发小组编写的。它诞生于 2003 年秋天&#xff0c;那时 Lawrence Journal-World 报纸的程序员 Adrian Holovaty 和…

泽攸科技无掩模光刻机:引领微纳制造新纪元

在当今科技迅猛发展的时代&#xff0c;微纳制造技术正变得越来越重要。泽攸科技作为这一领域的先行者&#xff0c;推出了其创新的无掩模光刻机&#xff0c;这一设备在微电子制造、微纳加工、MEMS、LED、生物芯片等多个高科技领域展现出了其独特的价值和广泛的应用前景。 技术革…

ubuntu中安装sublime-text

安装sublime-text 直接在software软件下载就好 安装成功后&#xff0c;如果找不到的话&#xff0c;可以在这里搜索。而后添加到收藏文件夹中。 下载的时候发生报错&#xff0c;发现是没有安装 ca-certificates 的软件包 &#xff1a; 命令&#xff1a; sudo apt install ca-c…

【NodeMCU实时天气时钟温湿度项目 6】解析天气信息JSON数据并显示在 TFT 屏幕上(心知天气版)

今天是第六专题&#xff0c;主要内容是&#xff1a;导入ArduinoJson功能库&#xff0c;借助该库解析从【心知天气】官网返回的JSON数据&#xff0c;并显示在 TFT 屏幕上。 如您需要了解其它专题的内容&#xff0c;请点击下面的链接。 第一专题内容&#xff0c;请参考&a…

uniapp小程序:大盒子包裹小盒子但是都有点击事件该如何区分?

在开发过程中我们会遇到这种情况&#xff0c;一个大盒子中包裹这一个小盒子&#xff0c;两个盒子都有点击事件&#xff0c;例如&#xff1a; 这个时候如果点击评价有可能会点击到它所在的大盒子&#xff0c;如果使用css中的z-index设置层级的话如果页面的盒子多的话会混乱&…

AI工具的热门与卓越:揭示AI技术的实际应用和影响

文章目录 每日一句正能量前言常用AI工具创新AI应用个人体验分享后记 每日一句正能量 我们在我们的劳动过程中学习思考&#xff0c;劳动的结果&#xff0c;我们认识了世界的奥妙&#xff0c;于是我们就真正来改变生活了。 前言 随着人工智能&#xff08;AI&#xff09;技术的快…

极端天气对气膜建筑有什么影响吗—轻空间

气膜建筑在近年来的发展迅速&#xff0c;逐渐替代了一部分传统建筑&#xff0c;展现了良好的市场前景。然而&#xff0c;面对自然环境中的极端天气&#xff0c;如暴风、暴雨和暴雪&#xff0c;气膜建筑是否能够经受住考验是大家关注的焦点。轻空间带您探讨一下这些极端天气对气…

【漏洞复现】泛微OA E-Cology ResourceServlet文件读取漏洞

漏洞描述&#xff1a; 泛微OA E-Cology是一款面向中大型组织的数字化办公产品&#xff0c;它基于全新的设计理念和管理思想&#xff0c;旨在为中大型组织创建一个全新的高效协同办公环境。泛微OA E-Cology ResourceServlet存在任意文件读取漏洞&#xff0c;允许未经授权的用户…

Nurbs曲线

本文深入探讨了Nurbs曲线的概念、原理及应用&#xff0c;揭示了其在数字设计领域的独特价值和广泛影响。Nurbs曲线作为一种强大的数学工具&#xff0c;为设计师们提供了更加灵活、精确的曲线创建方式&#xff0c;从而极大地提升了设计作品的质感和表现力。文章首先介绍了Nurbs曲…

大数据之 Hadoop概述

用最简洁的语言跟大家表达我最想分享的知识 。 什么是Hadoop Hadoop框架核心模块 HDFS MapReduce Yarn Hive HBase Phoenix Zookeeper Impala Spark 分布式计算-Spark与Impala与Presto与Tez 今天主要跟大家简述一下hadoop&#xff0c;主要是图片的形式跟大家介绍&#xff0c;希…

Rpcx (二):传输

一、Transport 传输 rpcx 可以通过 TCP、HTTP、UnixDomain、QUIC和KCP通信。你也可以使用http客户端通过网关或者http调用来访问rpcx服务。 TCP 这是最常用的通信方式。高性能易上手。可以使用TLS加密TCP流量。 Example: 101basic 服务端使用 tcp 做为网络名并且在注册中心…

稚晖君独家撰文:具身智能即将为通用机器人补全最后一块拼图

具身智能新纪元。 *本文为稚晖君独家供稿,「甲子光年」经智元机器人授权发布。稚晖君本名彭志辉,先后任职OPPO、华为,现为智元机器人CTO、首席架构师。 在ChatGPT之后,又一个大模型概念火了——具身智能(Embodied AI)。 在学术界,图灵奖得主、上海期智研究院院长姚期…

IOS 苹果IAP(内购)之创建沙盒账号

IOS 苹果IAP&#xff08;内购&#xff09;之创建沙盒账号 沙盒账号是什么&#xff1f;沙盒账号创建的前提条件沙盒账号创建沙盒账号使用流程沙盒账号注意事项 沙盒账号是什么&#xff1f; 如果IOS应用里面用到了苹果应用内付费&#xff08;IAP&#xff09;功能&#xff0c;那么…

办公软件_EdrawMax 免安装版教程 (亿图图示综合图形图表设计软件)

前言 万兴亿图图示(Wondershare EdrawMax)是一款综合图形图表设计软件,Visio国产替代.亿图图示中文版(Edraw Max)是一款办公绘图软件的思维导图软件.无需任何绘图功底,即可轻松创建各类思维导图.亿图图示专家,提供大量事例和在线模板,用于创建流程图,信息图,组织结构图,科学教…

面试题:调整数字顺序,使奇数位于偶数前面

题目&#xff1a; 输入一个整数数组&#xff0c;实现一个函数&#xff0c;来调整该数组中数字的顺序 使得所有奇数位于数组的前半部分&#xff0c;所有偶数位于数组的后半部分 算法1&#xff1a; 利用快速排序的一次划分思想&#xff0c;从2端往中间遍历 时间复杂度&#x…

day5

利用迭代器&#xff01; #include <vector> #include <map>class Solution { public:std::vector<int> intersection(std::vector<int>& nums1, std::vector<int>& nums2) {std::map<int, int> Mymap;std::vector<int> qq…

金万维动态域名小助手怎么用?

金万维动态域名小助手是一个域名检测工具&#xff0c;使用此工具可以进行检测域名解析是否正确、清除DNS缓存、修改DNS服务器地址及寻找在线客服&#xff08;仅支持付费用户&#xff09;等操作。对不懂网络的用户是一个很好的检测域名的工具&#xff0c;下面我就讲解一下金万维…