链表的顶级理解

news2024/11/23 19:01:01

目录

1.链表的概念及结构

2.链表的分类

 单向或者双向

 带头或者不带头

 循环或者非循环

3.无头单向非循环链表的实现

 3.1创建单链表

3.2遍历链表

3.3得到单链表的长度

3.4查找是否包含关键字

3.5头插法

 3.6尾插法

3.7任意位置插入

3.8删除第一次出现关键字为key的节点

3.9回收链表

3.10完整代码


1.链表的概念及结构

概念:

链表是一种 物理存储结构上非连续 存储结构,数据元素的 逻辑顺序 是通过链表中的 引用链接 次序实现的 。

结构:

实际在内存中每个节点的地址是随机的,只不过用这个节点的next,找到了下一个节点的地址,实现链接。 


2.链表的分类

 实际中链表的结构非常多样

 以下情况组合起来就有8种链表结构:

 单向或者双向

 带头或者不带头

 循环或者非循环

 

 我们重点掌握无头单向非循环链表,这种结构在笔试面试中出现很多。并且可以触类旁通其他结构。


3.无头单向非循环链表的实现

链表的功能与顺序表类似,无非是增删查改,在某位置的插入与删除,对数据内容进行管理和操作。

具体实现内容:

(1)创建单链表
(2)遍历链表
(3)得到单链表的长度
(4)查找是否包含关键字
(5)头插法
(6)尾插法
(7)任意位置插入
(8)删除第一次出现关键字为key的节点
(9)回收链表

 3.1创建单链表

public class MyLinkedList {
    class Node {
        public int val;
        public Node next;

        public Node(int val) {
            this.val = val;
        }
    }
    public Node head;// 代表当前链表的头节点的引用
}

3.2遍历链表

public void disPlay() {
        Node sur = head;
        while(sur  != null) {
            System.out.print(sur.val+" ");
            sur = sur.next;
        }
    }

3.3得到单链表的长度

进行遍历,并进行记录,最后进行返回就行

public int size(){
        int count = 0;
        Node cur = head;
        while (cur != null) {
            count++;
            cur = cur.next;
        }
        return count;
    }

3.4查找是否包含关键字

对链表进行遍历,然后一一比

 //查找是否包含关键字key是否在单链表当中
    public boolean contains(int key){
        Node cur = head;
        while (cur != null) {
            if(cur.val == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

3.5头插法

将第一个节点的地址赋给我们新添加的节点的next,并且将新添加的节点赋给head,作为新的头节点

  public void addFirst(int data){
        Node node = new Node(data);
        node.next = head;
        head = node;
    }

 3.6尾插法

首先对该链表进行遍历,当遍历到最后一个节点时,将新添加的节点的地址最后一个节点的next。

如果该链表为空,直接将该新增节点设为头节点

 public void addLast(int data){
        Node node = new Node(data);
        if(head == null) {
            head = node;
            return;
        }
        Node cur = head;
        while (cur.next != null) {
            cur = cur.next;
        }
        cur.next = node;
    }

3.7任意位置插入

需要插入的位置必须为合法,如果不合法,我们会抛出一个异常进行提醒

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

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

任意位置插入,我们可以分为种情况,插在开头,插在结尾,插在中间

插在结尾和插在中间可以总结成一种

    //任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data)
            throws ListIndexOutOfException{
        checkIndex(index);
        if(index == 0) {
            addFirst(data);
            return;
        }
       
        Node cur = findIndexSubOne(index);
        Node node = new Node(data);
        node.next = cur.next;
        cur.next = node;
    }

    /**
     * 找到 index-1位置的节点的地址
     * @param index
     * @return
     */
    private Node findIndexSubOne(int index) {
        Node cur = head;
        int count = 0;
        while (count != index-1) {
            cur = cur.next;
            count++;
        }
        return cur;
    }
    private void checkIndex(int index) throws ListIndexOutOfException{
        if(index < 0 || index > size()) {
            throw new ListIndexOutOfException("index位置不合法");
        }
    }

3.8删除第一次出现关键字为key的节点

分为四种情况

(1)一个节点都没有
(2)删除数据在第一个
(3)没有你要删除的数据
(4)有你要删除的数据且不是第一个

//删除第一次出现关键字为key的节点 O(N)
    public void remove(int key)throws ListIndexOutOfException{
        checkIndex(key);
        if(head == null) {
            return ;//一个节点都没有
        }
        //删除数据在第一个
        if(head.val == key) {
            head = head.next;
            return;
        }
        Node cur = searchPrev(key);
         //没有你要删除的数据
        if(cur == null) {
            return;
        }
        Node del = cur.next;//要删除的节点
        cur.next = del.next;
    }

    /**
     * 找到关键字key的前一个节点
     * @param key
     * @return
     */
    private Node searchPrev(int key) {
        Node cur = head;
        while (cur.next != null) {
            if(cur.next.val == key) {
                return cur;
            }
            cur = cur.next;
        }
        return null;//没有你要删除的节点
    }

3.9回收链表

将头节点置为空

public void clear() {
        head = null;
    }

3.10完整代码

public class MyLinkedList {
    class Node {
        public int val;
        public Node next;

        public Node(int val) {
            this.val = val;
        }
    }
    public Node head;// 代表当前链表的头节点的引用
    public void disPlay() {
        Node sur = head;
        while(sur  != null) {
            System.out.print(sur.val+" ");
            sur = sur.next;
        }
    }
    public int size(){
        int count = 0;
        Node cur = head;
        while (cur != null) {
            count++;
            cur = cur.next;
        }
        return count;
    }

    //查找是否包含关键字key是否在单链表当中
    public boolean contains(int key){
        Node cur = head;
        while (cur != null) {
            if(cur.val == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }
    public void addFirst(int data){
        Node node = new Node(data);
        node.next = head;
        head = node;
    }
    public void addLast(int data){
        Node node = new Node(data);
        if(head == null) {
            head = node;
            return;
        }
        Node cur = head;
        while (cur.next != null) {
            cur = cur.next;
        }
        cur.next = node;
    }
    //任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data)
            throws ListIndexOutOfException{
        checkIndex(index);
        if(index == 0) {
            addFirst(data);
            return;
        }

        Node cur = findIndexSubOne(index);
        Node node = new Node(data);
        node.next = cur.next;
        cur.next = node;
    }

    /**
     * 找到 index-1位置的节点的地址
     * @param index
     * @return
     */
    private Node findIndexSubOne(int index) {
        Node cur = head;
        int count = 0;
        while (count != index-1) {
            cur = cur.next;
            count++;
        }
        return cur;
    }
    private void checkIndex(int index) throws ListIndexOutOfException{
        if(index < 0 || index > size()) {
            throw new ListIndexOutOfException("index位置不合法");
        }
    }



    //删除第一次出现关键字为key的节点 O(N)
    public void remove(int key)throws ListIndexOutOfException{
        checkIndex(key);
        if(head == null) {
            return ;//一个节点都没有
        }
        //删除数据在第一个
        if(head.val == key) {
            head = head.next;
            return;
        }
        Node cur = searchPrev(key);
        //没有你要删除的数据
        if(cur == null) {
            return;
        }
        Node del = cur.next;//要删除的节点
        cur.next = del.next;
    }

    /**
     * 找到关键字key的前一个节点
     * @param key
     * @return
     */
    private Node searchPrev(int key) {
        Node cur = head;
        while (cur.next != null) {
            if(cur.next.val == key) {
                return cur;
            }
            cur = cur.next;
        }
        return null;//没有你要删除的节点
    }

    public void clear() {
        head = null;
    }

}

以上为我个人的小分享,如有问题,欢迎讨论!!! 

都看到这了,不如关注一下,给个免费的赞 

 

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

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

相关文章

ROS2与ROS1通信

文章目录 准备工作通信包安装启动ros1_bridge在ROS1中启动相机节点在ROS2中查看ROS1话题 准备工作 本机系统20.04 ROS2-foxyROS1-noetic 两个版本的ROS 均需要按照官网教程进行安装&#xff0c;安装完成以后&#xff0c;source环境变量都不放到~/.bashrc文件里面 通信包安装…

MES管理系统和MOM系统哪个更适合中小企业

中小型制造企业需要在选择制造管理系统前进行充分的需求分析和系统评估&#xff0c;结合企业的战略目标和资源状况来做出决策。MES和MOM系统是两种常见的制造管理系统&#xff0c;它们都能够帮助企业提高生产效率、降低生产成本&#xff0c;实现持续发展。然而&#xff0c;MES管…

模糊测试面面观 | 模糊测试对软件质量和性能的影响

随着软件行业的几十年发展和数字化转型的加快&#xff0c;我国已经度过了软件行业的野蛮发展时代。用户对软件的质量和性能要求越来越高&#xff0c;已经成为企业成功与否的至关重要条件。然而&#xff0c;随着软件规模的扩大和黑客攻击方式的多样化&#xff0c;保障软件的安全…

【kubernetes】Helm

什么是 Helm 每个成功的软件平台都有一个优秀的打包系统&#xff0c;比如Debian、Ubuntu 的 apt&#xff0c;RedHat、CentOS 的 yum。Helm 则是 Kubernetes上 的包管理器&#xff0c;方便我们更好的管理应用。 在没使用 helm 之前&#xff0c;向 kubernetes 部署应用&#xf…

昌硕科技、世硕电子同步上线法大大电子合同

近日&#xff0c;世界500强企业和硕联合旗下上海昌硕科技有限公司&#xff08;以下简称“昌硕科技”&#xff09;、世硕电子&#xff08;昆山&#xff09;有限公司&#xff08;以下简称“世硕电子”&#xff09;的电子签项目正式上线。上线仪式在上海浦东和硕集团科研大楼举行&…

VSCode如何为远程安装预设(固定)扩展

背景 在使用VSCode进行远程开发时&#xff08;python开发之远程开发工具选择_CodingInCV的博客-CSDN博客&#xff09;&#xff0c;特别是远程的机器经常变化时&#xff08;如机器来源于动态分配&#xff09;&#xff0c;每次连接新的远程时&#xff0c;都不得不手动安装一些开…

操作系统-笔记-第四章-文件管理

目录 四、第四章——文件管理 1、文件管理——基础概念 &#xff08;1&#xff09;文件结构 &#xff08;2&#xff09;操作系统提供的接口 &#xff08;3&#xff09;总结 2、文件的逻辑结构 &#xff08;1&#xff09;有结构文件&#xff08;类似SQL表文件&#xff09…

数据分析案例丨商品零售购物篮分析(下)

数据分析案例丨商品零售购物篮分析&#xff08;上&#xff09; 03 数据预处理 通过对数据探索分析&#xff0c;发现数据数据完整&#xff0c;并不存在缺失值。建模之前需要转变数据的格式&#xff0c;才能使用apriori函数进行关联分析。对数据进行转换&#xff0c;如代码清单…

TIA博途中的数据类型基本介绍

TIA博途中的数据类型基本介绍 基本数据类型 Bool 布尔 FALSE 或TRUE 举例: I0.0 Q0.2 M100.0 DB0.DBX2.5 Byte 字节 二进制:2#0000 0000 到2#1111 1111 无符号整数:0到255 有符号整数:-128到127 十六进制:16#00到16#FF 举例: IB2 MB100 DB1.DBB2 Word 字 二进制:2#0000 …

钉钉公布AI版本商业定价,调用一次大模型不到5分钱

8月22日&#xff0c;在2023年钉钉生态大会上&#xff0c;钉钉总裁叶军公布了钉钉全面智能化的最新进展&#xff1a;已有17条产品线、55个场景全面接入大模型&#xff0c;完成智能化再造&#xff1b;钉钉同时面向生态伙伴和客户开放智能化底座AI PaaS&#xff0c;表示将用大模型…

基于Java水果售卖系统设计与实现(论文+源码)_kaic

第1章 绪 论 1.1 课题研究的背景 随着信息技术的发展&#xff0c;互联网经济快速兴起&#xff0c;电子商务发展迅速&#xff0c;网上购物受到人们的广泛关注和普遍欢迎。水果传统售卖模式的缺点不断暴露&#xff0c;不能满足当今人们快节奏的生活模式需要。将水果的售卖带…

Dubbo服务

dubbo服务分为服务的提供者和消费者 1.服务提供者在nacos注册后通过 DubboService 暴漏服务 2.dubbo服务消费者通过 DubboReference来进行远程服务调用 dubbo的高级特性 1.启动检查&#xff1a;如果启动消费者无提供者则报错&#xff0c;通过配置文件check&#xff1a; fa…

实战演练 | Navicat 导入向导

数据库工具中的导入导出功能是指将数据从一个数据库系统导出到另一个数据库系统&#xff0c;或者将数据从一个文件格式导出到另一个文件格式。导入导出功能可以通过各种方式实现&#xff0c;例如使用SQL语句、数据库管理工具或第三方库和工具。在进行数据迁移时&#xff0c;通常…

排序算法合集

F B I W a r n i n g : \color{red}FBI \qquad Warning: FBIWarning: 本人没有完整的计算机科班的教育经历&#xff0c;但是一直在兢兢业业&#xff0c;努力学习。 这些排序函数都是自己零零散散写的&#xff0c;也没有经过深思熟虑和优化&#xff0c;纯粹是为了自娱自乐。 …

c++ qt--信号与槽(一) (第三部分)

c qt–信号与槽(一) &#xff08;第三部分&#xff09; 一.用qt自带的方法添加信号槽 1.第一种 1.如何添加 2.在何处进行绑定 2.第二种 1.如何添加 2.在何处进行绑定 而且会在mainwindow.h中添加槽函数的声明&#xff0c;在mainwindow.cpp中添加槽函数的定义 在mainwindow…

C语言入门 Day_8数据与运算小结

目录 前言 1.精度 2.运算 2.易错点 3.思维导图 前言 到目前为止我们一共学习了四种数据类型&#xff0c;他们分别是表示整数的整型&#xff1b;表示小数的浮点型&#xff1b;表示字符的字符型&#xff1b;和表示布尔数的布尔型。 表示整数的整型&#xff0c;它的变量类型名…

如何搭建智能问答FAQ的底层数据基础呢?

搭建智能问答FAQ的底层数据基础是构建一个高效和准确的问答系统的关键。在这篇文章中&#xff0c;我们将探讨如何搭建智能问答FAQ的底层数据基础&#xff0c;并介绍需要注意的几个方面。 一、了解智能问答FAQ的概念和优势 智能问答FAQ是一种基于人工智能技术的问答系统&#…

趣解设计原则之单一职责(论一个小老板的发家史)

一、前言 今天我们来聊一聊设计原则中的单一职责&#xff0c;还是按照惯例&#xff0c;先介绍一下含义&#xff0c;然后呢&#xff0c;我们再来讲一个小故事。 单一职责&#xff08;SRP&#xff1a;Single Reposibility Principle&#xff09;的定义&#xff1a; 一个类或者模…

static的使用

static的使用 在C语言中&#xff0c;static是一个关键字&#xff0c;用于指定变量、函数和代码块的作用域和生命周期。 用法&#xff1a; 静态变量 1.修饰变量&#xff1a;使用static关键字声明的变量是静态变量&#xff0c;它们的作用域被限制在定义它们的源文件中&#x…

SRE 与开发的自动化协同 -- 生产环境出现 bug 自动生成异常追踪

简介 生产环境 bug 的定义&#xff1a;RUM 应用和 APM 应用的 error_stack 信息被捕捉后成为 bug。 以 APM 新增错误巡检为例&#xff0c;当出现新错误时&#xff0c;在观测云控制台的「事件」模块下生成新的事件报告&#xff0c;捕捉为 bug。同时利用 Dataflux Func 创建异常…