数据结构(Java实现)LinkedList与链表(上)

news2024/11/17 11:43:10

链表
在这里插入图片描述
逻辑结构
在这里插入图片描述


在这里插入图片描述


无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。
无头双向链表:在Java的集合框架库中LinkedList底层实现就是无头双向循环链表。


链表的实现
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

创建一个链表
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


遍历单链表
在这里插入图片描述
在这里插入图片描述


得到单链表的长度 链表中节点的个数
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


查找是否包含关键字key是否在单链表当中
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


头插和尾插
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


任意位置的插入
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


删除第一次出现关键字为key的节点
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


删除所有值为key的节点
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


clear
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


上述单链表的所有代码
MySingleList

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

        public ListNode(int val) {
            this.val = val;
        }
    }
    public ListNode head;//一个特殊的节点,头节点

    //创建一个链表
    public void createList(){
        ListNode node1=new ListNode(23);
        ListNode node2=new ListNode(3);
        ListNode node3=new ListNode(253);
        ListNode node4=new ListNode(88);
        ListNode node5=new ListNode(56);
        ListNode node6=new ListNode(23);

        node1.next=node2;
        node2.next=node3;
        node3.next=node4;
        node4.next=node5;
        node5.next=node6;

        this.head=node1;
    }

    //遍历单链表
    public void show(){
        ListNode cur=head;
        while(cur!=null){
            System.out.print(cur.val+" ");
            cur=cur.next;
        }
        System.out.println();
    }

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

    //查找是否包含关键字key是否在单链表当中
    public boolean contains(int key){
        ListNode cur=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);
        //链表为空的情况下也是成立的
        node.next=head;
        head=node;
    }

    //尾插
    public void addLast(int data){
        ListNode node=new ListNode(data);
        if(head==null){
            head=node;
            return;
        }
        //不能使用while(cur!=null),当cur==null时,说明已经错过了最后一个节点
        //使用下面这种
        ListNode cur=head;
        while(cur.next!=null){//这里会漏掉空链表的情况,我们在上面一步补充
            cur=cur.next;
        }
        cur.next=node;
    }

    //任意位置插入(后面插入)
    public void addIndex(int index,int data){
        int len=size();
        //判断index位置的合法性
        if(index<0||index>len){
            throw new IndexOut("任意位置插入,坐标不合法");
        }
        if(index==0){
            addFirst(data);
            return;
        }
/*        if(index==len){
            addLast(data);
            return;
        }*/
        ListNode node=new ListNode(data);
        //一般情况,找到这个index节点的位置
        ListNode cur=findIndex(index);
        node.next=cur.next;
        cur.next=node;

    }
    private  ListNode findIndex(int index){
        ListNode cur=head;
        while(index-1!=0){
            cur=cur.next;
            index--;
        }
        return cur;//第index位置的节点
    }

    //删除第一次出现关键字为key的节点
    public void remove(int key){
        if(head==null){
            return;
        }
        if(head.val==key){//因为在searchPrev中的判断条件为prev.next==null,忽略掉了头节点,这里补充判断
            head=head.next;
            return;
        }
        ListNode prev=searchPrev(key);
        if(prev==null){
            System.out.println("没有这个数据");
            return;
        }
        ListNode del=prev.next;
        prev.next=del.next;
    }
    private ListNode searchPrev(int key){
        ListNode prev =head;
        while(prev.next!=null){//这里将会使用双指针,prev为待删除节点的前一个节点,因此判断条件要使用prev.next==null,而不是prev==null
            if(prev.next.val==key){//上面的条件为遍历链表,这里的条件为判断条件
                return prev;
            }else{
                prev=prev.next;
            }
        }
        return null;
    }

    //删除所有值为key的节点
    public void removeAllKey(int key){
        if(head==null){
            return;
        }
        ListNode cur=head.next;
        ListNode prev=head;
        while(cur!=null){
            if(cur.val==key){
                prev.next=cur.next;
                cur=cur.next;
            }else{
                prev=cur;
                cur=cur.next;
            }
        }
        if(head.val==key){//观察到前面的cur为head.next,漏掉了对head的val值的判断,这里补充上
            head=head.next;
        }
    }

    //clear
    public void clear(){
        this.head=null;
    }

}

IndexOut

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

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

Test1

public class Test1 {
    public static void main(String[] args) {
        MySingleList mySingleList=new MySingleList();
/*        mySingleList.createList();

        mySingleList.show();
        System.out.println(mySingleList.size());
        System.out.println(mySingleList.contains(100));
        System.out.println(mySingleList.contains(23));
        mySingleList.show();*/
        mySingleList.addFirst(23);
        mySingleList.addFirst(2);
        mySingleList.addFirst(3);
        mySingleList.addFirst(230);
        mySingleList.show();
        mySingleList.addLast(-13);
        mySingleList.addLast(-178);
        mySingleList.show();
        MySingleList mySingleList1=new MySingleList();
        mySingleList1.addLast(45);/*
        mySingleList1.show();

        mySingleList.addIndex(3,999);
        try{
            mySingleList.addIndex(4,999);
        } catch (IndexOut e) {
            e.printStackTrace();
        }
        mySingleList.addIndex(mySingleList.size(), 56);*/

/*        mySingleList.show();
        mySingleList.remove(88);
        mySingleList.remove(23);
        mySingleList.show();
        mySingleList.remove(230);*/
/*        mySingleList.show();
        mySingleList.addIndex(3,33);
        mySingleList.addIndex(5,33);
        mySingleList.show();
        mySingleList.removeAllKey(33);
        mySingleList.show();

        mySingleList.addIndex(0,33);
        mySingleList.show();
        mySingleList.removeAllKey(33);*/
        mySingleList.show();
        mySingleList.clear();
        mySingleList.show();
        System.out.println("#######");




    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Stylet框架

Stylet框架 编辑时间:2023/8/25 1.Stylet简介 Stylet是一个小巧但功能强大的MVVM框架&#xff0c;灵感来自Caliburn.Micro。其目的是进一步降低复杂性和魔力&#xff08;译者注&#xff1a;Caliburn.Micro有很多让人抓狂的约定&#xff0c;看起来像魔法&#xff0c;这对新手…

项目进度管理(4-2)关键链法和关键路径法的区别和联系

1 关键链法和关键路径法的主要区别 1.1 关键链法和关键路径法的关注焦点不同 关键路径法&#xff08;CPM&#xff09;&#xff1a;关注项目中最长的路径&#xff0c;也就是所需时间最长的路径&#xff0c;这被称为关键路径。关键路径决定了项目的最早完成时间。关键链法&…

Jetbrains IDE新UI设置前进/后退导航键

背景 2023年6月&#xff0c;Jetbrains在新发布的IDE&#xff08;Idea、PyCharm等&#xff09;中开放了新UI选项&#xff0c;我们勾选后重启IDE&#xff0c;便可以使用这一魔性的UI界面了。 但是前进/后退这对常用的导航键却找不到了&#xff0c;以前的设置方式&#xff08;Vi…

【2022年电赛】有人开摆,有人跑路,有人5秒不识数

前言&#xff1a;该作品是2022年四川省电子设计竞赛一等奖作品&#xff0c;其能稳定完成全部四个问题&#xff0c;但存在停车距离的精度问题。该文章将会介绍该作品的整体设计思路&#xff0c;关键控制算法等技术相关问题&#xff0c;也会给出工程的下载链接。同时本人参加过20…

考研408 | 【操作系统】 内存管理

内存的基础 内存和内存的作用&#xff1a; 几个常用的数量单位&#xff1a; 指令的工作原理&#xff1a; 问题&#xff1a;如何将指令中的逻辑地址转换为物理地址&#xff1f; 解决办法&#xff1a;装入的三种方式 1.绝对装入 2.可重定位装入 3.动态重定位 从写程序到程…

分布式事务篇-2.2 Seata存储模式,配置模式,注册模式

文章目录 前言一、存储模式:1.1 存储模式的作用&#xff1a;1.2 File 存储模式&#xff1a;1.2.1 映射数据存储文件&#xff1a;1.2.3 file存储优缺点&#xff1a; 1.3 db 存储模式&#xff1a;1.3.1 application.yml 配置db 信息&#xff1a;1.3.1 拷贝驱动jar&#xff1a;1.3…

实验室信息化建设都包括哪些方面?

在现代的计算机通信系统、信息安全系统和自动控制等系统中&#xff0c;软件开发工作占了相当大的比重&#xff0c;而与这些系统有关的软件一般十分庞大&#xff0c;也相当复杂。这些软件还要大量地与操作系统核作深层次的交互&#xff0c;以进行信息的传输、控制和实现各种通信…

#systemverilog# 之 event region 和 timeslot 仿真调度(六)疑惑寄存器采样吗

一 象征性啰嗦 想必大家在刚开始尝试写Verilig HDL代码的时候,都是参考一些列参考代码,有些来自于参考书,有些来自于网上大牛的笔记,甚至有写来自于某宝FPGA开发板的授权代码。我还记得自己当时第一次写代码,参考的是一款Altera 芯片,结合Quartus 开发软件, 在上面练习…

线程池也就那么一回事嘛!

线程池详讲 一、线程池的概述二、线程池三、自定义线程池四、线程池工作流程图五、线程池应用场景 一、线程池的概述 线程池其实就是一种多线程处理形式&#xff0c;处理过程中可以将任务添加到队列中&#xff0c;然后在创建线程后自动启动这些任务。这里的线程就是我们前面学过…

算法笔记:KD树

1 引入原因 K近邻算法需要在整个数据集中搜索和测试数据x最近的k个点&#xff0c;如果一一计算&#xff0c;然后再排序&#xff0c;开销过大 引入KD树的作用就是对KNN搜索和排序的耗时进行改进 2 KD树 2.1 主体思路 以空间换时间&#xff0c;利用训练样本集中的样本点&…

OSPF配置与协议分析

一、实验目的&#xff1a; 通过该实验学习OSPFv2协议&#xff0c;能够通过GNS3模拟环境并用wireshark抓包分析OSPFv2协议的报文格式 二、预备知识&#xff1a; OSPF(Open Shortest Path First&#xff0c;开放式最短路径优先&#xff09;是一个链路状态路由协议&#xff0c;被各…

智能引领物流,AGV与工控机完美搭配!

AGV小车现已广泛被制造业使用&#xff0c;成为智能工厂、智能车间的重要组成部分。在制造业的生产中用AGV小车代替工进行装载、搬运、卸载等工作&#xff0c;实现了车间物流的自动化&#xff0c;极大的提高了生产自动化水平。通过AGV小车与产线进行完美结合&#xff0c;可自动化…

如何理解原假设和备择假设?

原假设H0&#xff1a;一般是想要推翻的结论&#xff0c;如指标没有变化&#xff0c;实验组和对照组的该结果指标没有差异等。 备择假设H1&#xff1a;一般是想要证明的结论&#xff0c;如实验组的指标是显著提升的&#xff0c;指标提升10%等。 反证法的思想&#xff1a;因为假…

到目前为止,所有的关于安卓14的详细介绍

安卓14现在可能已经不远了,谷歌已经进行了五次测试,通常10月份的发布窗口时间很快就会到来。但除了在谷歌I/O 2023上进行简短讨论外,谷歌对正在发生的变化相对沉默。 可以肯定地说,Android 14不会是操作系统有史以来最大的一系列变化,但有很多改进和变化可以让Android保持…

Python Requests模块session的使用建议

本篇主要讲解Python Requests模块session的使用建议及整个会话中的所有cookie的方法。 测试代码 服务端&#xff1a;下面是用flask做的一个服务端&#xff0c;用来设置cookie以及打印请求时的请求头。 # -*- coding: utf-8 -*- from flask import Flask, make_response, req…

容器的基本操作

docker中的容器就是一个轻量级的虚拟机&#xff0c;是镜像运行起来的一个状态&#xff0c;本文就先来看看容器的基本操作。 查看容器 查看容器 启动docker后&#xff0c;使用docker ps命令可以查看当前正在运行的容器&#xff1a; 查看所有容器 上面这条命令是查看当前正在…

Hadoop Hdfs基本命令

0目录 1.hadoop安装问题处理 2.hdfs基本命令 3.上传/下载文件和文件夹 1.hadoop安装问题处理 如果安装有进程无法启动&#xff0c;如下图 重新检查6个配置文件 Core-site.xml \ hdfs-site.xml \ hadoop-env.sh \ yarn-site.xml \ workers \ yarn-site.xml 来到hadoop313目录…

8/26 回溯法 周总结 记录个人的想法

DAY1 77. 组合 这道题是经典的回溯题&#xff0c; 递归函数参数和返回值显而易见 终止条件是path.size()k 递归逻辑&#xff0c;需要理解每次调用回溯的startIndex的含义&#xff0c;图解&#xff1a; DAY2 216. 组合总和 III:这道题与77题作类比&#xff1a; 77&#xff1…

剪绳子c、c++实现

给你一根长度为 n 的绳子&#xff0c;请把绳子剪成整数长的 m 段&#xff08; m 、 n 都是整数&#xff0c; n > 1 并且 m > 1 &#xff0c; m < n &#xff09;&#xff0c;每段绳子的长度记为 k[1],...,k[m] 。请问 k[1]*k[2]*...*k[m] 可能的最大乘积是多少&#x…