Java单链表和LinkedList的实现

news2025/1/24 5:45:55

一、单链表的实现

                无头单向非循环链表

定义异常用于判断所给位置是否合法

public class IndexNotLegal extends RuntimeException{
   public IndexNotLegal(){

   }
   public IndexNotLegal(String smg){
       super(smg);
   }
}

class ListNode中包含当前节点的值和下一个节点指向 

实现链表的头插,尾插,任意位置插入,查找,删除一个节点,打印,计数,清空 

import java.util.List;

public class MySingleList {
    //节点
    class ListNode{
        public int val;
        public ListNode next;

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

    public ListNode head;//代表链表的头结点
    //打印
    public void display(){
        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;
    }

    //头插
    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;
        }
        ListNode tail = head;
        while(tail.next != null){
            tail=tail.next;
        }
        tail.next = node;
  }

  //任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data){
        //判断合不合法
        try {
            checkIndex(index);
        }catch(IndexNotLegal e){
            e.printStackTrace();
        }

        if(index==0){
            addFirst(data);
            return;
        }
        if(index == size()){
            addLast(data);
            return;
        }
        ListNode cur = findIndexSubOne(index);
        ListNode node = new ListNode(data);
        node.next = cur.next;
        cur.next = node;
    }
    private void checkIndex(int index) throws IndexNotLegal{
        if(index<0||index>size()){
            throw new IndexNotLegal("index不合法");
        }
    }
    public ListNode findIndexSubOne(int index){
        ListNode cur = head;
        int count =0;
        while(count!=index-1){
            cur = cur.next;
            count++;
        }
        return cur;
    }
 //查找是否包含关键字key是否在单链表当中
    public boolean contains(int key){
        ListNode cur = head;
        while(cur!=null){
            if(cur.val==key){
                return true;
            }
            cur = cur.next;
        }
        return false;
 }
 //删除出现关键字为key的节点
    public void remove(int key){
        if(head==null){
            return;
        }
        ListNode del = head;
        ListNode pre = head;
        while(del!=null){
            if(del.val==key){
                pre.next = del.next;
                del = del.next;
            }else{
            pre = del;
            del = del.next;
            }
        }
        if(head.val==key){
            head = head.next;
            return;
        }//最后判断头结点
 }

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

二、LinkedList

1、介绍

LinkedList的底层是双向链表结构,由于链表没有将元素存储在连续的空间中,元素存储在单独的节点中,然后通过引用将节点连接起来了,因此在任意位置插入或者删除元素时,不需要搬移元素,效率比较高。

        LinkedList实现了List接口

        LinkedList的底层使用了双向链表

        LinkedList没有实现RandomAccess接口,因此LinkedList不支持随机访问

        LinkedList的任意位置插入和删除元素时效率比较高,时间复杂度为O(1)

        LinkedList比较适合任意位置插入的场景

2、方法介绍

        add

直接增加

插入到指定位置

 addAll:尾插c 中的所有元素

         remove

删除 index 位置元素

删除遇到的第一个 o

 get:获取下标 index 位置元素

set:将下标 index 位置元素设置为 element

clear:清空

contains:判断 o 是否在线性表中

indexOf:返回第一个 o 所在下标

lastIndexOf:返回最后一个 o 的下标

subList:截取部分 list

三、LinkedList遍历方法

public static void main1(String[] args) {
        LinkedList<Integer> list = new LinkedList<>();
        list.add(1);
        list.add(2);
        list.add(1,3);

        System.out.println(list);//直接打印
        System.out.println("==============");
        
        //foreach遍历
        for(Integer x: list){
            System.out.print(x+" ");
        }
        System.out.println();
        System.out.println("============");

        //for遍历
        int size = list.size();
        for (int i = 0; i < size; i++) {
            System.out.print(list.get(i)+" ");
        }
        System.out.println();
        System.out.println("============");
        
         //使用迭代器遍历-正向遍历
        Iterator<Integer> it = list.iterator();
        while(it.hasNext()){
            System.out.print(it.next()+" ");
        }
        System.out.println();
        System.out.println("============");

        Iterator<Integer> it2 = list.listIterator();
        while(it2.hasNext()){
            System.out.print(it2.next()+" ");
        }
        System.out.println();
        System.out.println("============");

        //使用迭代器遍历-反向遍历
        ListIterator<Integer> it3 = list.listIterator(list.size());
        while(it3.hasPrevious()){
            System.out.print(it3.previous()+" ");
        }
        System.out.println();
        System.out.println("============");
    }

 

 四、实现MyLikedList

        无头双向链表

定义异常用于判断所给位置是否合法

public class IndexNotIllegal extends RuntimeException{
    public IndexNotIllegal(){

    }
    public IndexNotIllegal(String smg){
        super(smg);
    }
}

方法实现 

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

        public ListNode(int val){
            this.val = val;
        }
    }
    public ListNode head;//头结点
    public ListNode last;//尾节点

    public int size(){
        int size = 0;
        ListNode cur = head;
        while(cur!=null){
            size++;
            cur = cur.next;
        }
        return size;
    }
    public void display(){
        ListNode cur = head;
        while(cur!=null){
            System.out.print(cur.val+" ");
            cur = cur.next;
        }
        System.out.println();
    }
    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);
        if(head==null){
            head = last = Node;
        }else{
        Node.next = head;
        head.prev = Node;
        head = Node;
        }
    }
    //尾插法
    public void addLast(int data){
        ListNode Node = new ListNode(data);
        if(head==null){
            head = last = Node;
        }else{
            last.next = Node;
            Node.prev = last;
            last = Node;
        }
    }
    //任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data){
        try{
            checkIndex(index);
        }catch(RuntimeException e){
            e.printStackTrace();
        }
        if(index == 0){
            addFirst(data);
            return;
        }
        if(index == size()){
            addLast(data);
            return;
        }
        ListNode cur = findIndex(index);
        ListNode node = new ListNode(data);
        node.prev = cur.prev;
        node.next = cur;
        cur.prev.next = node;
        cur.prev = node;

    }
    private ListNode findIndex(int index){
        ListNode cur = head;
        while(index!=0){
            cur = cur.next;
            index--;
        }
        return cur;
    }
    public void checkIndex(int index)throws IndexNotIllegal{
        if(index<0||index>size()){
            throw new IndexNotIllegal("数组下标不合法");
        }
    }
    //删除第一次出现关键字为key的节点
    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;
                        last = last.prev;
                    } else {
                        cur.prev.next = cur.next;
                        cur.next.prev = cur.prev;
                    }
                }
                return;//删完一个就跳出
            }
            cur = cur.next;
            }
    }

    //删除所有值为key的节点
    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;
                        last = last.prev;
                    } else {
                        cur.prev.next = cur.next;
                        cur.next.prev = cur.prev;
                    }
                }
            }
            cur = cur.next;
        }
    }
    //得到单链表的长度
    public void clear(){
        ListNode cur = head;
        while(cur!=null){
            ListNode curN = cur.next;
            cur.next = null;
            cur.prev = null;
            cur = curN;
        }
        head = last = null;
    }

}

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

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

相关文章

摄影杂记二

一、相机操作指南 ⑴按键说明&#xff1a; 除了常规的几个模式&#xff0c;里面就特殊场景可以看一下&#xff0c;有全景&#xff0c;支持摇摄。 lock&#xff1a;多功能锁。可以锁定控制按钮和控制环。在设置中找到多功能锁&#xff0c;可以设置锁定什么。 m-fn&#xff1a;多…

自定义校验器

1.前端校验 <template><el-dialog:title"!dataForm.brandId ? 新增 : 修改":close-on-click-modal"false":visible.sync"visible"><el-form:model"dataForm":rules"dataRule"ref"dataForm"keyu…

解决方案AssertionError: Torch not compiled with CUDA enabled

文章目录 一、现象二、解决方案 一、现象 报错显示 s torch.from_numpy(padding_seq([s])).cuda().long() File "D:\Anaconda3\lib\site-packages\torch\cuda\__init__.py", line 221, in _lazy_initraise AssertionError("Torch not compiled with CUDA ena…

基于微信小程序的亿家旺生鲜云订单零售系统的设计与实现(论文+源码)_kaic

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了亿家旺生鲜云订单零售系统的开发全过程。通过分析亿家旺生鲜云订单零售系统管理的不足&#xff0c;创建了一个计算机管理亿家旺生鲜云订单零售系统的方案。文章介…

Text-Driven Object Detection 关于结合文本的目标检测

1、简单介绍 首先说明&#xff0c;本文目的主要是水一篇CSDN博客&#xff0c;顺便说一下和标题相关的认识。 近几年&#xff0c;在目标检测领域关于多模态的目标检测工作已成了主流&#xff0c;趋势仍在延续&#xff0c;未来仍有很大挖掘空间。这里说的多模态不是简单的多源数…

Sql优化篇-干货总结大全

前言 我们经常会听到Sql优化的一个概念&#xff0c;但其实sql优化不一定就是说sql语句写的有问题&#xff0c;它可能是因为cpu资源爆满&#xff0c;或者内存空间不足&#xff0c;它也会导致sql执行卡顿&#xff1b;或者说表设计层面&#xff0c;过滤条件没有加索引之类的 等等…

【STL】list的底层原理及其实现

文章目录 list的介绍list的整体结构设计list的构造代码模拟实现&#xff1a; list节点类的实现list 迭代器Iterator的使用以及实现Iterator的使用Iterator的底层实现反向迭代器 list与vector的比较实现list类 list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列…

springCloud-LoadBalancer负载均衡微服务负载均衡器LoadBalancer

2020年前SpringCloud是采用Ribbon作为负载均衡实现&#xff0c;但是在2020后采用了LoadBalancer替代 LoadBalancer默认提供了两种负载均衡策略&#xff08;只能通过配置类来修改负载均衡策略&#xff09; 1.RandomLoadBalancer-随机分配策略 2.RoundRobinLoadBalancer-轮询分配…

【WSN覆盖优化】基于灰狼优化算法的无线传感器网络覆盖 GWO-WSN覆盖优化【Matlab代码#74】

文章目录 【可更换其他算法&#xff0c;获取资源请见文章第5节&#xff1a;资源获取】1. 灰狼优化算法2. WSN节点感知模型3. 部分代码展示4. 仿真结果展示5. 资源获取 【可更换其他算法&#xff0c;获取资源请见文章第5节&#xff1a;资源获取】 1. 灰狼优化算法 此处略。 2.…

尚硅谷html5+css3(1)html相关知识

1.基本标签&#xff1a; <h1>最大的标题字号 <h2>二号标题字号 <p>换行 2.根标签<html> 包括<head>和<body> <html><head><title>title</title><body>body</body></head> </html> 3…

Golang单元测试和压力测试

一.单元测试 1.1 go test工具 go语言中的测试依赖go test命令。编写测试代码和编写普通的Go代码过程类似&#xff0c;并不需要学习新的语法&#xff0c;规则和工具。 go test命令是一个按照一定约定和组织的测试代码的驱动程序。在包目录内&#xff0c;所有以_test.go为后缀名的…

2.网络编程-HTTP和HTTPS

目录 HTTP介绍 HTTP协议主要组成部分 GET 和 POST有什么区别 常见的 HTTP 状态码有哪些 http状态码100 HTTP1.1 和 HTTP1.0 的区别有哪些 HTTPS 和 HTTP 的区别是什么 HTTP2 和 HTTP1.1 的区别是什么 HTTP3 和 HTTP2 的区别是什么 HTTPS的请求过程 对称加密和非对称…

SVG图标显示

SVG图标显示 1.安装SharpVectors.Wpf包 2.添加引用 xmlns:svgc"http://sharpvectors.codeplex.com/svgc/"3.加载svg文件&#xff0c;生成操作选择资源(Resource) 4.UI界面显示SVG图像 <Button Click"OnSaveFileClick" ToolTip"Save Svg File…

云原生安全当前的挑战与解决办法

云原生安全作为一种新兴的安全理念&#xff0c;不仅解决云计算普及带来的安全问题&#xff0c;更强调以原生的思维构建云上安全建设、部署与应用&#xff0c;推动安全与云计算深度融合。所以现在云原生安全在云安全领域越来受到重视&#xff0c;云安全厂商在这块的投入也是越来…

蓝桥杯—PCF8951

1.整个系统靠SDA和SCL实现完善的全双工数据传输 2.引脚图 AN1为光明电阻 AN3为滑动变阻 A0-A2均接地 时钟线连P20 地址线连P21 实物图 iic总线 谁控制时钟线谁是主设备 时序相关 官方提供的底层驱动代码 /* # I2C代码片段说明1. 本文件夹中提供的驱动代码供参赛选手完成…

Octopus V2:设备端super agent的高级语言模型

论文&#xff1a;Octopus v2: On-device language model for super agent论文地址&#xff1a;https://arxiv.org/abs/2404.01744模型主页&#xff1a;https://huggingface.co/NexaAIDev/Octopus-v2 Octopus-V2-2B Octopus-V2-2B 是一款具有20亿参数的开源先进语言模型&#…

SQL Sever 2008 安装教程

先从官网下载程序&#xff1a;下载地址 打开上述链接后&#xff0c;点击下载按钮。 就会跳出下面这个界面&#xff0c;如果你的电脑是64位的请选择下图中这两个程序。 下载完成后&#xff0c;在电脑磁盘中找到这两个文件&#xff0c;注意安装的顺序&#xff0c;先安装 SQLEXPR…

校园圈子小程序,大学校园圈子,三段交付,源码交付,支持二开

介绍 在当今的数字化时代&#xff0c;校园社交媒体和在线论坛成为了学生交流思想、讨论问题以及分享信息的常用平台。特别是微信小程序&#xff0c;因其便捷性、用户基数庞大等特点&#xff0c;已逐渐成为构建校园社区不可或缺的一部分。以下是基于现有资料的校园小程序帖子发…

蓝桥杯每日一题:杨辉三角形(组合计数)

下面的图形是著名的杨辉三角形&#xff1a; 如果我们按从上到下、从左到右的顺序把所有数排成一列&#xff0c;可以得到如下数列&#xff1a; 1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 6, 4, 1, ... 给定一个正整数 N&#xff0c;请你输出数列中第一次出现 N是在第几个数&#x…

LeetCode-74. 搜索二维矩阵【数组 二分查找 矩阵】

LeetCode-74. 搜索二维矩阵【数组 二分查找 矩阵】 题目描述&#xff1a;解题思路一&#xff1a;先二分查找行&#xff0c;再二分查找列。解题思路二&#xff1a;暴力遍历&#xff0c;也能过。解题思路三&#xff1a;用python的in。 题目描述&#xff1a; 给你一个满足下述两条…