双向无头非循环链表的简单实现及介绍

news2024/10/5 14:25:27

前言

        欢迎大家阅读小奥奇的新作,听说上一篇我们留下了一点点 “ 简单的题目 ” ,我们在本篇要干什么呢,请看本篇任务!

本篇任务概述:

        1、解决 “ 简单的遗留题目 ”

        2、 LInkedList(双向)的使用

        3、简单的自我模拟 LinkedList 的实现

        4、ArrayList 和 LinkedList 的区别


一、解决 “ 简单的遗留题目 ”

1.1 反转一个单链表 

public ListNode reverseList(ListNode head) {
        if(head==null){
            return null;
        }
        ListNode cur=head;
        while(cur.next!=null){
            ListNode lim=cur.next;
            cur.next=lim.next;
            lim.next=head;
            head=lim;
        }
        return head;
    }

 解题思路如下: 

      主要使用头插法(前篇讲到过),从第二个节点开始,先判断 head 是否为空,若为空则返回 null,否则令 cur = head,使用 while 遍历链表,当 cur.next 不为空时,初始化下一个节点,使  lim = cur.next,接着使当前节点的下一个结点 cur.next 设置为下一个节点的下一个节点 lim.next,再使下一个节点的下一个节点 lim.next 指向头节点 head,将头节点设置为 lim 即可

1.2 给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点

class Solution {
    public ListNode middleNode(ListNode head) {
        if(head==null||head.next==null){
            return head;
        }
        ListNode fast=head;
        ListNode slow=head;
        while(fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
        }
        return slow;
    }
}

 解题思路如下:

先判断头节点是否为空或是否只含一个节点,定义两个指针:快指针 fast 和慢指针 slow,使用 while( fast!= null && fast.next != null )遍历链表,使快指针 fast 一次走两个节点,慢指针 slow 一次走一个节点,当快指针 fast 为空或其下一节点为空时,结束循环,此时 slow 所在位置即为中间节点

1.3 链表的回文结构

class Solution {
    public boolean isPalindrome(ListNode head) {
        if(head==null){
            return true;
        }
        ListNode fast=head;
        ListNode slow=head;
        while(fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
        }
        ListNode cur=slow;
        while(cur.next!=null){
            ListNode lim=cur.next;
            cur.next=lim.next;
            lim.next=slow;
            slow=lim;
        }
        while(head!=slow){
            if(head.val!=slow.val){
                return false;
            }
            if(head.next==slow){
                return true;
            }
            head=head.next;
            slow=slow.next;
        }
        return true;
    }
}

 解题思路如下: 

判断链表是否为空,如何和上题一样,找到中间节点,接着从中间节点出进行逆置,然后用while 遍历链表,当遍历的过程有不相等之处,即该链表不存在回文结构,否则存在回文结构

题目都解决完毕,若有不明白或错误之处,请大家在评论区提出,相信大家做完收获满满,第三题难道相对大啦点,但是和前两题联系紧密,接下来我们将介绍 LinkedList 的使用


二、LinkedList(双向)的使用

2.1 什么是LinkedList?

LinkedList 的官方文档icon-default.png?t=O83Ahttps://docs.oracle.com/javase/8/docs/api/java/util/LinkedList.html LinkedList的底层是双向链表结构,由于链表没有将元素储存在连续的空间,而是储存在单独的节点中,用引用将各个节点连接起来,所以在任意位置插入或删除元素都比较方便。

2.2 LinkedList的使用 

2.3 LinkedList的构造


三、简单的自我模拟 LinkedList 的实现

  代码如下:(大家自行观看,我就不解释啦)

public class LinkedList implements IList{
    static class ListNode{
        private int val;
        private ListNode prev;
        private ListNode next;

        public ListNode(int val) {
            this.val = val;
        }
    }
    private ListNode head;
    private ListNode last;
    public void addFirst(int data) {
        ListNode node=new ListNode(data);
        if(head==null){
            head=last=node;
        }else {
            node.prev = null;
            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=last.next;
        }
    }
    private void checki(int index) throws Illegalindex{
        if(index<0||index>size()){
            throw new Illegalindex("输入的索引不合法!!!");
        }
    }
    public void addIndex(int index, int data) throws Illegalindex{
        try{
            checki(index);
            ListNode node=new ListNode(data);
            if(index==0){
                addFirst(data);
                return;
            }
            if(index==size()){
                addLast(data);
                return;
            }
            ListNode cur=head;
            while(index!=0){
                cur=cur.next;
                index--;
            }
            node.next=cur;
            node.prev=cur.prev;
            cur.prev.next=node;
            cur.prev=node;
        }catch(Illegalindex e){
            System.out.println("增加的位置不合法!!!");
            e.printStackTrace();;
        }
    }
    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 {
                    cur.prev.next = cur.next;
                    if (cur.next == null) {
                        last = last.prev;
                    } else {
                        cur.next.prev = cur.prev;
                    }
                }
                return;
            }
            cur = cur.next;
        }
    }
    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 {
                    cur.prev.next = cur.next;
                    if (cur.next == null) {
                        last = last.prev;
                    } else {
                        cur.next.prev = cur.prev;
                    }
                }
            }
            cur = cur.next;
        }
    }
    public int size() {
        ListNode cur=head;
        int len=0;
        while(cur!=null){
            len++;
            cur=cur.next;
        }
        return len;
    }

    public void clear() {
        ListNode cur=head;
        while(cur!=null){
            ListNode curn=cur.next;
            cur.next=null;
            cur.prev=null;
            cur=curn;
        }
        head=last=null;
    }
    public boolean contains(int toFind) {
        ListNode cur=head;
        while(cur!=null){
            if(cur.val==toFind){
                return true;
            }
        }
        return false;
    }
    public void display() {
        ListNode cur=head;
        for (int i = 0; i < size(); i++) {
            System.out.print(cur.val+" ");
            cur=cur.next;
        }
        System.out.println();
    }
}

      上述代码实现了 IList 接口,以及抛出了自定义异常,前面文章都有涉及并讲解。


四、ArrayList LinkedList 的区别

       ArrayList LinkedList Java中的两种不同的集合实现方式。下面是它们之间的区别:

    1. 内部实现:

       ArrayList 是基于数组实现的,LinkedList是基于双向链表实现的。

    2. 插入和删除操作的效率:

       ArrayList 在尾部插入和删除元素的效率较高,时间复杂度为O(1),而在中间插入和删除元素的效率较低,因为需要移动其他元素,时间复杂度为O(n)。而 LinkedList 在任意位置插入和删除元素的效率都较高,时间复杂度为O(1)

    3. 随机访问的效率:

        ArrayList 支持随机访问操作,即可以通过索引快速访问任意位置的元素,时间复杂度为O(1)。而 LinkedList 则不支持随机访问,需要从头或尾开始遍历链表,时间复杂度为O(n)

    4. 内存消耗:

        ArrayList需要连续的内存空间来存储元素,所以在元素较多时可能会占用较大的内存空间。而LinkedList不需要连续的内存空间,它只需要为每个元素存储指向前后节点的引用,所以在元素较多时可能会占用较小的内存空间。

        根据具体的使用场景,选择 ArrayList 还是 LinkedList 会有不同的优劣势。如果需要频繁的随机访问和对尾部的增删操作较多,可以选择 ArrayList;如果需要频繁的在任意位置插入和删除操作,可以选择 LinkedList

 


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

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

相关文章

2.1MyBatis——ORM对象关系映射

2.1MyBatis——ORM对象关系映射 1. 验证映射配置2.ResultType和ResultMap2.1ResultMap是最终的ORM依据2.2ResultType和ResultMap的使用区别 3.具体的转换逻辑3.1 TypeHandle类型转换 5.总结 概括的说&#xff0c;MyBatis中&#xff0c;对于映射关系的声明是由开发者在xml文件手…

“2024年最流行的10个前端框架”

大多数时候&#xff0c;前端开发人员需要使用一组组合语言来构建他们的前端 Web 应用程序。 HTML 负责网页中的基本布局&#xff0c;CSS 管理视觉格式和结构&#xff0c;JavaScript 用于维护交互性和功能。在这篇文章中&#xff0c;我们将了解最好的前端框架&#xff0c;这些框…

FL Studio 24.1.2.4381中文版免费下载及FL Studio 24最新使用学习教程

家好呀&#xff0c;作为一个资深的音乐爱好者和制作人&#xff0c;今天我要安利一个我最近超级痴迷的数字音频工作站软件——FL Studio24.1.2.4381中文版。这款产品可是让我的音乐创作之路如虎添翼&#xff0c;快来跟我一起看看它的炫酷功能吧&#xff01; 最近接到很多小伙伴的…

2024 ciscn WP

一、MISC 1.火锅链观光打卡 打开后连接自己的钱包&#xff0c;然后点击开始游戏&#xff0c;答题八次后点击获取NFT&#xff0c;得到有flag的图片 没什么多说的&#xff0c;知识问答题 兑换 NFT Flag{y0u_ar3_hotpot_K1ng} 2.Power Trajectory Diagram 方法1&#xff1a; 使用p…

操作系统实验之银行算法

一、实验目的 采用高级语言编写一个动态分配系统资源的程序&#xff0c;模拟死锁现象&#xff0c;观察死锁发生的条件&#xff0c;并采用适当的算法&#xff0c;有效地防止死锁的发生。 二、实验内容 本次实验采用银行算法防止死锁的发生。设有3个并发进程共享10个系统资源。在…

1c语言基础

1.关键字 一、数据类型关键字 A基本数据类型&#xff08;5个&#xff09; void&#xff1a;声明函数无返回值或无参数&#xff0c;声明无类型指针&#xff0c;显式丢弃运算结果char&#xff1a;字符型类型数据&#xff0c;属于整型数据的一种int&#xff1a;整型数据&#x…

Ollama 运行视觉语言模型LLaVA

Ollama的LLaVA&#xff08;大型语言和视觉助手&#xff09;模型集已更新至 1.6 版&#xff0c;支持&#xff1a; 更高的图像分辨率&#xff1a;支持高达 4 倍的像素&#xff0c;使模型能够掌握更多细节。改进的文本识别和推理能力&#xff1a;在附加文档、图表和图表数据集上进…

Github界面学习

之前并没有使用到其他功能大多数是看代码&#xff0c;然后看discussion&#xff1b; now,在做毕设的时候发现了一个gymnasium关于异步环境的bug&#xff0c;查看github发现已经被修复了&#xff1b; 因此希望学习一下修复者是在哪个module修复以及如何修复以及提交代码&#…

Spring Boot框架在大学生就业招聘中的应用

3系统分析 3.1可行性分析 通过对本大学生就业招聘系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本大学生就业招聘系统采用JAVA作为开发语言&#xff0c;S…

kaggle实战3RossmanStore商店销售额预测XgBoost解决回归问题案例1

kaggle实战2信用卡反欺诈逻辑回归模型案例1 数据集下载地址 https://download.csdn.net/download/AnalogElectronic/89844637 https://tianchi.aliyun.com/dataset/89785 加载数据 #预测销售额 回归问题 import numpy as np import pandas as pd import matplotlib.pyplot a…

无神论文解读之ControlNet:Adding Conditional Control to Text-to-Image Diffusion Models

一、什么是ControlNet ControlNet是一种能够控制模型生成内容的方法&#xff0c;能够对文生图等模型添加限制信息&#xff08;边缘、深度图、法向量图、姿势点图等&#xff09;&#xff0c;在当今生成比较火的时代很流行。 这种方法使得能够直接提供空间信息控制图片以更细粒…

招联2025校招内推倒计时

【投递方式】 直接扫下方二维码&#xff0c;或点击内推官网https://wecruit.hotjob.cn/SU61025e262f9d247b98e0a2c2/mc/position/campus&#xff0c;使用内推码 igcefb 投递&#xff09; 【招聘岗位】 后台开发 前端开发 数据开发 数据运营 算法开发 技术运维 软件测试 产品策…

【课程学习】随机过程之泊松过程

随机过程之泊松过程 泊松分布泊松过程 泊松分布 二项分布是离散性的分布&#xff0c;泊松分布是把二项分布取n趋于无穷得到的连续分布。也就是在一段时间内不停的观察某件事情发生的次数。 如&#xff1a;一个小时内观察一段路上经过行人的数目&#xff0c;如果每个半个小时观…

nginx和gateway的关系和区别

在技术选型时&#xff0c;选择 Nginx 和 Spring Cloud Gateway&#xff08;或简称为 Gateway&#xff09;主要取决于具体应用场景和技术需求。下面是两者的一些关键差异和适用场景。 一、Nginx 概念 Nginx 是一个高性能的 Web 服务器和反向代理服务器&#xff0c;常被用作静…

智能手表(Smart Watch)项目

文章目录 前言一、智能手表&#xff08;Smart Watch&#xff09;简介二、系统组成三、软件框架四、IAP_F411 App4.1 MDK工程结构4.2 设计思路 五、Smart Watch App5.1 MDK工程结构5.2 片上外设5.3 板载驱动BSP5.4 硬件访问机制-HWDataAccess5.4.1 LVGL仿真和MDK工程的互相移植5…

CSRF | CSRF 漏洞介绍

关注这个漏洞的其他相关笔记&#xff1a;CSRF 漏洞 - 学习手册-CSDN博客 0x01&#xff1a;CSRF 漏洞简介 CSRF&#xff08;Cross-Site request forgery&#xff0c;跨站请求伪造&#xff09;也被称为 One Click Attack 或者 Session Riding&#xff0c;通常缩写为 CSRF 或者 X…

【Java】IntelliJ IDEA开发环境安装

一、下载 官方地址&#xff1a;https://www.jetbrains.com/idea/ 点击Download直接下载 二、安装 双击安装包&#xff0c;点击Next 选择安装路径&#xff0c;点击Next 勾选安装内容 安装完成。 三、创建项目 打开IDEA&#xff0c;填写项目名称&#xff0c;选择项目安装路径…

S7-200 SMART的数据类型说明

S7-200 SMART的数据主要分为&#xff1a; 与实际输入/输出信号相关的输入/输出映象区&#xff1a; I&#xff1a;数字量输入&#xff08;DI&#xff09;Q&#xff1a;数字量输出&#xff08;DO&#xff09;AI&#xff1a;模拟量输入AQ&#xff1a;模拟量输出 内部数据存储区…

STM32 Hal库SDIO在FATFS使用下的函数调用关系

STM32 Hal库SDIO在FATFS使用下的函数调用关系 本文并不将FATFS的相关接口操作&#xff0c;而是将HAL在使用FATFS通过SDIO外设管理SD卡时&#xff0c;内部函数的调用逻辑&#xff0c;有助于当我们使用CUBEMX生成FATFS读取SD卡的代码时无法运行时Debug。本文也会说明一些可能出现…

如何编写一个优雅的commit message

在Git中&#xff0c;git commit 命令扮演着至关重要的角色。它的主要作用是将暂存区&#xff08;staging area&#xff09;里的改动内容提交到本地仓库&#xff08;repository&#xff09;中&#xff0c;形成一个新的版本或提交&#xff08;commit&#xff09;。这个过程是 Git…