iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >一篇文章带你玩转JAVA单链表
  • 822
分享到

一篇文章带你玩转JAVA单链表

2024-04-02 19:04:59 822人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录一、链表 1. 概念2. 结构二、单向不带头非循环链表 1. 概念及结构2. 链表的实现三、链表面试题四、总结一、链表  1. 概念 链表是一种物理

一、链表 

1. 概念

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

上章介绍到顺序表适合用作查询和修改,而不适合用作插入和删除。并且它增容时容易造成空间浪费。而链表则具有以下的特点

适合用作插入和删除随用随取,避免了空间的浪费不适合用作查询和修改 

2. 结构

链表其实可以想象成一条被打了一些结的绳子

而实际上,链表就是由一个个节点构成的,只不过每个节点一般有两个域

数值域 data: 里面存储数据

next 域: 里面存储的是下一个节点的地址(是引用变量)

其中

尾节点: 当这个节点的 next 域为 null 时,该节点就是尾节点

头节点: 整个链表的第一个节点就是头节点

实际中的链表结构非常多,通过以下的情况的组合可以有8种链表的结构(比如带头单向循环链表就是一种)

单向、双向

带头节点、不带头

节点循环、非循环

而上图所示,就是一个单向不带头非循环链表。

可能有人会疑问,上述图片中不是存在头节点吗?那为啥它又是一个不带头节点的链表呢?我将上述图片实例稍稍改一下就是带头节点的了

我在原有的头节点前面又多了一个节点,并且这个节点的数值域里面的数据可有可无,因为对其没有影响。而这里面的头节点只是一个标志,标识这个节点是该链表的头

那带头节点的和不带头结点的链表有啥差别呢?

不带头: 这个链表的头节点可能发生改

变带头: 这个链表的头节点不会发生改变

那循环链表又是啥样的呢?我们可以将上述单向不带头非循环链表稍微修改一下

即将尾节点的 next 域存储了头节点的地址

我们知道一个节点一般就两个域,但如果是双向链表,则就有三个域了

数值域 data: 里面存储数据

next 域: 里面存储的是下一个节点的地址(是引用变量)

prev 域: 里面存储的是上一个节点的地址(是引用变量)

我们画一个不带头双向非循环链表就是这样的

接下来我将主要介绍单向不带头非循环链表和双向不带头非循环链表,这两种链表也是经常出现在面试题中的

二、单向不带头非循环链表 

1. 概念及结构

上述通过图解,大家应该对单向不带头非循环链表应该有了了解。那么代码中该怎么实现呢?

我们知道,链表应该可以看作一个类,而节点本身其实也可以抽象的看作成一个类

首先对于节点类,代码可以写出这样


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

先定义了数值域,再定义了 next 域(由于 next 存储的是下一个节点的地址,故写出上述那样)。而我们初始时可以知道 val,所以可以写个构造函数对 val 进行初始化,而该节点的 next 域初始时是不可能知道的,所以不对 next 做初始化

如果创造一个 Node 对象就可以写出

Node node = new Node(10);

即头节点的数值域为10。

再定义链表类,代码可以写成这样


public class MyLinkedList {
    public Node head;
}

我们定义了一个头节点,这是我们很容易发现的,就比如我要对该链表进行头插,则该链表的头节点一直都在改变。所以写上述的代码就是为了标识单链表的头节点。

2. 链表的实现

接下来我们来实现单向不带头非循环链表的一些操作

打印链表


public void display(){
    Node cur =this.head;
    while(cur!=null){
        System.out.print(cur.val + " ");
        cur=cur.next;
    }
    System.out.println();
}

求链表的长度


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

查找值 key 是否在单链表中


public boolean contains(int key){
    Node cur=this.head;
    while(cur!=null){
        if(key==cur.val){
            return true;
        }
        cur=cur.next;
    }
    return false;
}

清除单链表


public void clear(){
    this.head.val=0;
    this.head.next=null;
}

头插法


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

尾插法


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

通过下标找到前驱节点(第一个节点下标为0)


public Node searchPrev(int index){
    Node cur = this.head;
    int count=0;
    while(count!=index-1){
        cur=cur.next;
        count++;
    }
    return cur;
}

任意位置插入


public void addIndex(int index, int data){
    if(index<0 || index>size()){
        throw new RuntimeException("index 不合法");
    }
    if(index==0){
        addFirst(data);
        return;
    }
    if(index==size()) {
        addLast(data);
        return;
    }
    Node node =new Node(data);
    Node cur =searchPrev(index);
    node.next=cur.next;
    cur.next=node;
}

通过值 key 找到前驱节点(第一个节点下标为0)


public Node searchPrevNode(int key){
    Node cur = this.head;
    while(cur.next!=null){
        if(cur.next.val==key) {
            return cur;
        }
        cur=cur.next;
    }
    return null;
}

删除第一次出现的值为 key 的节点


public void remove(int key){
    if(this.head==null){
        return;
    }
    if(key==this.head.val){
        this.head=this.head.next;
        return;
    }
    Node node = searchPrevNode(key);
    if(node==null){
        System.out.println("链表中无要删除的元素");
    }else {
        node.next = node.next.next;
    }
}

删除所有出现的值为 key 的节点


public void removeAllKey(int key){
    if(this.head==null){
        return;
    }
    Node prev=this.head;
    Node cur=this.head.next;
    while(cur!=null){
        if(cur.val==key){
            cur=cur.next;
            prev.next=cur;
        }else{
            prev=cur;
            cur=cur.next;
        }
    }
    if(this.head.val==key){
        this.head=this.head.next;
    }
}

呼,写的我人傻了

你以为结束了吗?NO!下面还有一大波链表面试题等着我和你,冲吧,牛牛!

三、链表面试题

删除链表中等于给定值 val 的所有节点 OJ 链接

反转一个单链表 OJ 链接

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

输入一个链表,输出该链表中倒数第k个结点 OJ 链接

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的 OJ 链接

编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前 OJ 链接

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针 OJ 链接

链表的回文结构 OJ 链接

输入两个链表,找出它们的第一个公共结点 OJ 链接

给定一个链表,判断链表中是否有环 OJ 链接

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null OJ 链接

如果你已经可以轻松应对上述题目了,可以继续去下面的链接中做题 LeetCode OJ 链接 和 牛客 OJ 链接

四、总结

今天简单了解了链表,以及对单向不带头非循环链表做了一些基操的实现。下章将包含个人的上述前11道 OJ 题的题解,以及了解双向不带头非循环链表

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: 一篇文章带你玩转JAVA单链表

本文链接: https://www.lsjlt.com/news/134181.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 一篇文章带你玩转JAVA单链表
    目录一、链表 1. 概念2. 结构二、单向不带头非循环链表 1. 概念及结构2. 链表的实现三、链表面试题四、总结一、链表  1. 概念 链表是一种物理...
    99+
    2022-11-12
  • 一篇文章带你玩转TiDB灾难恢复
    高可用是 TiDB 的另一大特点,TiDB/TiKV/PD 这三个组件都能容忍部分实例失效,不影响整个集群的可用性。下面分别说明这三个组件的可用性、单个实例失效后的后果以及如何恢复。 TiDB TiDB 是无状态的,推荐至少部署两个实...
    99+
    2017-09-22
    一篇文章带你玩转TiDB灾难恢复
  • 一篇文章带你玩转go语言的接口
    目录一.其他语言二.go语言三.go接口实现多态四.空接口的使用(重点)4.1定义4.2空接口使用4.3空接口几个要注意的坑(我刚学时的错误)总结一.其他语言 其他语言中所提供的接口...
    99+
    2022-11-12
  • 一篇文章带你用C语言玩转结构体
    目录前言一、结构体的声明与定义1.结构体的声明2.结构成员的类型3.结构体的定义二、初始化结构体三、访问结构体成员四、结构体嵌套五、结构体指针六、结构体传参总结前言 C语言提供了不同...
    99+
    2022-11-12
  • JavaScript一文带你玩转web表单网页
    一、前言 前面我们介绍了web网页的快速开发,这次我们讲点更深层次些的,看这面之前建议先看 上篇,之后在食用这篇。 二、正文部分 如图示:点击webapp上面的小三角形点到直到看到j...
    99+
    2022-11-12
  • 一篇文章带你学会Spring MVC表单标签
    目录form 标签input 标签password 标签checkbox 标签checkboxes 标签radiobutton 与 radiobuttons 标签select 与 o...
    99+
    2023-03-24
    springmvc表单标签用法示例 springmvc表单标签 springmvc接收表单参数
  • 一篇文章带你搞定JAVA Maven
    目录1、maven是什么,为什么存在?项目结构是什么样子,怎么定位jar2、Idea 的操作1.新建maven项目2.配置仓库3.添加依赖,添加fastjson的依赖4.打包项目3、...
    99+
    2022-11-12
  • 一篇文章带你入门Java Script
    目录概述特点和Java的区别弱类型语言强类型语言书写位置数组函数JS中的自定义对象(扩展内容)Object形式的自定义对象JS中的事件常用的事件:动态注册基本步骤:DOM模型总结概述...
    99+
    2022-11-12
  • 一篇文章带你了解Java SpringBoot Nacos
    目录1、什么是Nacos 1.1与eureka对比1.2与zookeeper对比1.3与springcloud config 对比 2、Spring Cloud Alibaba 套件...
    99+
    2022-11-12
  • 一篇文章带你搞定JAVA泛型
    目录1、泛型的概念2、泛型的使用3、泛型原理,泛型擦除3.1 IDEA 查看字节码3.2 泛型擦除原理4、?和 T 的区别5、super extends6、注意点1、静态方法无法访问...
    99+
    2022-11-12
  • 一篇文章带你搞定JAVA注解
    目录1、注解是什么2、jdk支持的注解有哪些2.1 三种常用的注解:2.2 元注解3、注解实例1、自定义注解2、在对应的方法上增加注解3、在项目启动的时候检查注解的枚举4、总结1、注...
    99+
    2022-11-12
  • 一篇文章带你搞定JAVA反射
    目录1、反射的概念1、概念2、获取字节码文件对象的方式2.1 元数据的概念2.2 获取class对象的方式1、访问权限2、获取方法2.1 访问静态方法2.2 访问类方法 3...
    99+
    2022-11-12
  • 一篇文章带你了解Java Stream流
    目录一、Stream流引入现有一个需求:1.用常规方法解决需求2.用Stream流操作集合,获取流,过滤操作,打印输出二、Stream流的格式三、获取流四、Stream流的常用方法方...
    99+
    2022-11-12
  • 一篇文章带你入门Java接口
    目录什么是接口:关键字:创建接口代码展示:如何实现接口呢:实现接口代码展示:具体代码实现:接口继承和类继承的区别:总结什么是接口: 接口是一系列方法的声明,是一些方法特征的集合 注...
    99+
    2022-11-12
  • 一篇文章带你入门Java封装
    目录什么是封装如何实现封装代码展示构造方法注意点:代码展示总结封装的优点什么是封装 Java中的封装是将数据(变量)和作用于数据(方法)的代码作为一个单元包装在一起的机制。 在封装中...
    99+
    2022-11-12
  • 一篇文章带你入门Java继承
    目录Java中继承什么是继承:为什么要用继承:学习总结:继承关键字:extends总结Java中继承 什么是继承: 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实...
    99+
    2022-11-12
  • 一篇文章带你入门Java变量
    目录引言概念变量的四个基本属性如何定义变量如何使用变量变量的特点总结引言 ♀ 小AD:明哥,我终于出了这口恶气了。 ♂ 明世隐:打爽了是吧。 ♀ 小AD:那必须的,打十盘我赢九盘,...
    99+
    2022-11-12
  • 一篇文章带你入门java方法
    目录方法的使用什么是方法方法的语法基本语法代码示例注意事项方法的调用调用规则代码示例方法的重载引例使用重载重载规则方法递归递归定义代码示例递归执行过程分析总结方法的使用 什么是方法 ...
    99+
    2022-11-12
  • 一篇文章带你入门java泛型
    目录一、什么是泛型二、语法三、示例1、简单示例2、返回最大值-支持各种数据类型3、泛型类4、类型通配符总结一、什么是泛型 Java 泛型(generics)是 JDK 5 中引入的一...
    99+
    2022-11-12
  • 一篇文章带你入门java集合
    目录一、简介1、java集合框架图2、集合框架体系3、Set和List的区别二、ArrayList1、定义2、用实例了解ArrayList三、LinkedList1、语法2、示例四、...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作