算法通关村第一关-链表青铜挑战笔记

news2024/10/5 17:18:17

文章目录

  • 前言
  • 一、Java的链表是怎么构造的?
    • 单链表的构造
      • 简介:
    • 构造链表:
  • 链表增加元素,首部,中间和尾部分别会有什么问题,需要怎么处理?
    • 链表的新增
      • 在头部添加元素:
      • 在中间添加元素:
      • 在尾部添加元素:
      • 链表的新增元素:
  • 链表删除元素,首部,中间和尾部分别会有什么问题,需要怎么处理?
    • 链表的删除
      • 在头部删除元素
      • 在中间删除元素
      • 在尾部删除元素
      • 链表的删除元素:
  • 双链表是如何构造的,如何实现元素的插入和删除?
  • 总结


前言

提示:努力把算法搞通透:

一、Java的链表是怎么构造的?

单链表的构造

简介:

我的回答:
链表的主要结构:数据和下一个节点的指针

在这里插入图片描述

public class Node {
    public int val;
    public Node next;
    public Node(int data){
        this.val = data;
        this.next =  null;
    }
}

🐟聪明的回答:
链表是一种常见的数据结构,用于存储和组织数据。它由一系列节点组成,每个节点包含两部分:数据和指向下一个节点的指针。
链表中的节点可以分为两类:头节点和普通节点。头节点是链表的起始节点,它通常不包含实际的数据,而只是用来指示链表的开头。普通节点用于存储实际的数据。
链表中的节点是通过指针连接在一起的。每个节点的指针指向下一个节点,从而组成了节点之间的链式关系。这种链式结构使得我们可以在链表中高效地插入、删除和查找节点。
相对于数组等连续存储的数据结构,链表的优点是在插入和删除节点时具有更好的灵活性。由于链表中的节点不需要连续的内存空间,我们可以很容易地在任意位置插入或删除节点,而不需要移动其他节点。
然而,链表的缺点是对于随机访问节点的效率较低。由于链表中的节点不是连续存储的,我们需要从头节点开始沿着链表遍历,直到找到目标节点。因此,链表在需要频繁随机访问节点的情况下可能不是最佳选择。
常见的链表类型包括单链表、双向链表和循环链表。在单链表中,每个节点只包含指向下一个节点的指针。双向链表中,每个节点不仅包含指向下一个节点的指针,还包含指向前一个节点的指针。循环链表是一种特殊的链表,其中最后一个节点的指针指向第一个节点,形成一个循环。
链表在计算机科学中被广泛应用,特别是在动态数据结构的实现中。它们可以用于构建堆栈、队列和哈希表等高级数据结构,并用于解决各种实际问题。

构造链表:

代码如下(示例):

private static Node initLinkedList(int[] array) {
    Node head = null, cur = null;
    for (int i = 0; i < array.length; i++) {
        Node newNode = new Node(array[i]);
        // 为什么?
        newNode.next = null;
        if (i == 0) {
            // 表示头结点
            head = newNode;
            cur = newNode;
        } else {
            // 非头节点的下一个节点(注意:这里是cur节点的下一个)
            cur.next = newNode;
            cur = newNode;
        }
    }
    return head;
}

该处使用的url网络请求的数据。


链表增加元素,首部,中间和尾部分别会有什么问题,需要怎么处理?

链表的新增

一个很重要的方法(获取链表长度)

/**
 * 获取链表长度
 *
 * @param head 链表头节点
 * @return 链表长度
 */
public static int getLength(Node head) {
    int count = 0;
    // 一般情况下保留头节点不丢
    Node node = head;
    // 注意不是if 是while(if只执行一次)
    while (node != null) {
        node = node.next;
        count++;
    }
    return count;
}

在头部添加元素:

head.next = head; (转移下一个头节点就行)【当然前提需要head != null

在中间添加元素:

找到目标节点的前一个??
targetNode 
tatgetNode.next = cur.next;
cur.next = targetNode; [顺序不能颠倒]
注意:不要这样去写  链表容易断开。
cur.next = targetNode

在尾部添加元素:

找到最后一个的前一个??
和头节点的方式一致
cur.next = null;[这样就保证最后一个元素不可达,也就失去意义->最终JVM被回收掉]

链表的新增元素:

/**
 * 链表插入
 *
 * @param head       链表头节点
 * @param nodeInsert 待插入节点
 * @param position   待插入位置,取值从2开始
 * @return 插入后得到的链表头节点
 */
public static Node insertNode(Node head, Node nodeInsert, int position) {
    // 考虑这三个参数的设计

    // 首先当然要考虑 头节点为空的情况
    if(head == null){
        return nodeInsert; //直接返回要插入的节点
    }
    // 考虑边界问题
    int length = getLength(head);
    if (position > length + 1 || position < 1){
        throw new IllegalArgumentException("Invalid position  非法参数异常");
    }

    // 考虑只有一个节点的情况/ 头节点非空
    // 且插入第一个节点
    // 注意:保留头节点的

    if (position == 1){
        nodeInsert.next = head;
    //   node.next = nodeInsert;// 这里位置搞错了
        // 保留原来的头节点形式
        head = nodeInsert;
        return head;
    }

    // 接下来考虑 在中间的问题了
    // 要找到目标节点的上一个
    Node pnode = head;
    int count = 1;//记住从 1 开始
    while(count < position -1){
        pnode.next = pnode;
        count++;
    }
    // 此时node (cur = 目标节点的上一个)
    // 不要这样写
    // node.next = nodeInsert.next;// 此时链表已经断了
    nodeInsert.next = pnode.next;
    pnode.next = nodeInsert;
    
    return head;

}

链表删除元素,首部,中间和尾部分别会有什么问题,需要怎么处理?

链表的删除

在头部删除元素

这个很简单-只需要将头节点换一下就行了
head = head.next; [当然还要判断链表是否为空🤩]

在中间删除元素

提示:todo:

在尾部删除元素

这个也是找到最后节点的前一个节点
让前一个节点指向null就行了【断链的基本操作😂】
cur.next = null;

链表的删除元素:

 /**
     * 删除节点
     *
     * @param head     链表头节点
     * @param position 删除节点位置,取值从1开始
     * @return 删除后的链表头节点
     */
    public static Node deleteNode(Node head, int position) {
       // 校验参数
       // 确定 head 为空的特例
        if (head == null){
            return null;
        }

        // 判断边界问题
        int length = getLength(head);
//        position < 1   不行 =1 成立
        if (position > length || position <= 0){
            throw new IllegalArgumentException("Invalid position 非法参数异常");
        }

        // 如果删除的位置是头节点的话
        // 这个比较特殊 也容易才处理
        int count = 1;
        if(position == 1){// 记住从 1 开始
            return head.next;// 直接返回head的下一个节点
        }
//        else {
//            // 在中间的话
//            // 因为链表不可逆 我们要操作两个节点
//            // 即跳过要删除的节点
//            Node preNode = head;
//            while(count < position - 1){
//                preNode = preNode.next;
//                count++;
//            }
//            Node curNode = preNode.next;
//            preNode.next = curNode.next;
//        }
        Node preNode = head; // 类似保留头节点  搞一个前驱【毕竟链表不可逆】
        while(count < position){
            preNode = preNode.next; //
            count++;
            Node curNode = preNode.next;
            preNode.next = curNode.next;// 跳过一个节点
        }
        return head;

    }

双链表是如何构造的,如何实现元素的插入和删除?

提示:todo:

总结

提示:todo:

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

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

相关文章

IP库新增多种颜色转换空间IP

颜色空间转换是图像及视频中常用的解决方案&#xff0c;涉及hsv-rgb、rgb-ycrcb等一些常见的颜色空间互相转换&#xff0c;今天带来几种常见的颜色空间转换IP&#xff0c;主要如下&#xff1a; IP库简介 一直想做一个可以供大家学习、使用的开源IP库&#xff0c;类似OpenCores&…

美化图表——LiveCharts中的时序图的制作,相对问题的解决

美化图表——LiveCharts中的时序图的制作&#xff0c;相应问题的解决 前言一、效果展示二、基本的一些实现的代码1.X,Y坐标的相关设置2.新增波形对象3.实时更新数据 三、修改的点总结 前言 在项目中&#xff0c;需要用到图表来展示波形的实时变化&#xff0c;故找到了这个Live…

优维低代码实践:统计视图

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…

35.Vue自定义指令-总结

目录 1.自定义指令容易踩的坑 1.1 指令名如果是多个单词&#xff0c;要使用kebab-case命名方式&#xff0c;不要用camelCase命名 1.2 指令回调函数中的this问题 1.3 局部指令与全局指令 2.自定义指令总结 2.1 定义语法&#xff1a; (1).局部指令 (2).全局指令 2.2 配置…

3.14 Bootstrap 缩略图

文章目录 Bootstrap 缩略图添加自定义的内容 Bootstrap 缩略图 本章将讲解 Bootstrap 缩略图。大多数站点都需要在网格中布局图像、视频、文本等。Bootstrap 通过缩略图为此提供了一种简便的方式。使用 Bootstrap 创建缩略图的步骤如下&#xff1a; 在图像周围添加带有 class …

ChatGPT | 修改RetrievalQA推荐答案的数量

知识库经常遇到一个问题会在一个文件的多处或者多个文件出现&#xff0c;这时候如果只回答一个结果就欠佳&#xff0c;最理想的做法是模仿推荐功能&#xff0c;把合适的多个答案及其出处汇总给用户。 如图&#xff0c;一个接口文档里面提到多处“http请求URL”&#xff1a; 使…

vue项目如何部署?有遇到布署服务器后刷新404问题吗?

一、如何部署 前后端分离开发模式下,前后端是独立布署的,前端只需要将最后的构建物上传至目标服务器的web容器指定的静态目录下即可 我们知道vue项目在构建后,是生成一系列的静态文件

Minecraft 1.20.x Forge模组开发 01.Idea开发环境配置

我们本次来进行Minecraft 1.20.x 模组开发环境配置教程的介绍。 效果演示 效果演示 效果演示 1.首先我们需要下载Java17和1.20模组开发包: Java17下载官网

csdn新星计划vue3+ts+antd赛道——利用inscode搭建vue3(ts)+antd前端模板

文章目录 ⭐前言⭐利用inscode免费开放资源&#x1f496; 在inscode搭建vue3tsant项目&#x1f496; 调整配置&#x1f496; antd 国际化配置&#x1f496; 用户store&#x1f496; 路由权限&#x1f496; 预览 ⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享…

【字节流】读数据(一次读一个字节数组数据)

字节流读数据&#xff08;一次读一个字节数组数据&#xff09; 1.需求&#xff1a; 把文件fos.txt中的内容读取出来在控制台输出 2.思路&#xff1a; 创建字节输入流对象调用字节输入流对象的读数据方法释放资源 package com.bytestream; import java.io.FileInputStream; …

TCP/IP网络编程 第十五章:套接字和标准I/O

标准I/O函数的优点 标准I/O函数的两个优点 将标准I/O函数用于数据通信并非难事。但仅掌握函数使用方法并没有太大意义&#xff0c;至少应该 了解这些函数具有的优点。下面列出的是标准I/O函数的两大优点: □标准I/O函数具有良好的移植性(Portability) □标准I/O函数可以利用缓…

stable diffusion windows本地搭建的坑

刚刚2小时前&#xff0c;我搭好了&#xff0c;欣喜若狂&#xff0c;开放端口&#xff0c;同事也尝试了。我的配置 16G内存&#xff0c;AMD卡&#xff0c;有gpu但是没有用。这里不说具体步骤&#xff0c;只说坑点。 首先就是安装gfpgan、clip、openclip问题&#xff0c;我参考…

短视频seo矩阵系统源码开发部署

目录 短视频矩阵源码部署步骤简单易懂&#xff0c;开发者只需按照以下几个步骤进行操作&#xff1a; 代码展示---seo关键词分析 开发要点&#xff1a; 代码展示如下&#xff1a; 开发部署注意事项&#xff1a; 说明&#xff1a;本开发文档适用于短视频seo矩阵系统源码开发…

如何理解 dutu输光定理

解决问题 1 dutu 拿100是赌一次好&#xff0c;还是100次1元的好&#xff1f; 一般的地方&#xff0c;如果不是公平赌局&#xff0c;而期望是负数的话 其实du次数越多越亏 2 1%就基本能决定胜负 了 3 千万不要陷入常人思维&#xff0c;用筹码数量思考&#xff0c;输光为止&am…

Windows与Linux取证分析

目录 一、电子数据取证基本概念 1.电子取证学 2.常规取证 3.洛卡德物质交换原理 4.电子数据范围 5.电子数据取证的概念和目的 6.电子数据取证过程 二、Linux系统取证 1.基本信息获取 &#xff08;1&#xff09;获取系统基础信息 &#xff08;2&#xff09;用户/用户…

centos 安装pyzbar

需求&#xff1a; 运行程序报错 ImportError: Unable to find zbar shared library 进程&#xff1a; 直接使用yum 安装 yum install python-devel && yum install zbar-devel 有时候会能成功&#xff0c;大多数时候python-devel 能成功但是 zbar-devel 会失败 下载…

数据代码分享|R语言基于逐步多元回归模型的天猫商品流行度预测

全文链接&#xff1a;https://tecdat.cn/?p33212 本文通过利用回归模型对天猫商品流行度进行了研究&#xff0c;确定了决定天猫商品流行度的重要因素。并讲述、论证了预测天猫商品流行度是天猫商品交易的至关重要的环节。通过对天猫商品流行度预测技术的发展和探讨&#xff0c…

ModuleNotFoundError: No module named ‘neobolt.packstream._packer‘解决办法

python打包完成后运行报下述错误 在打包得python文件加入以下包&#xff0c;重新打包&#xff0c;问题解决 代码如下&#xff1a; import neobolt.packstream.packer import neobolt.packstream.unpacker import neobolt.bolt.io

PostgreSQL 的就业前景如何?

PostgreSQL的就业前景非常广阔&#xff0c;它是一种功能强大、可靠且开源的关系型数据库管理系统。以下是说明PostgreSQL就业前景的几个关键点&#xff1a; 1.高需求&#xff1a;随着企业和组织对数据存储和管理的需求不断增长&#xff0c;对数据库专业人员的需求也在持续上升…

基于linux下的高并发服务器开发(第二章)- 2.11 匿名管道概述

03 / 匿名管道 04 / 管道的特点 05 / 为什么可以使用管道进行进程间的通信 管道对应一个读端&#xff0c;一个写端。比如说往父进程的文件描述符5 往管道里面写数据&#xff0c;子进程的文件描述符6读出数据。 06 / 管道的数据结构 07 / 匿名管道的使用