附学习笔记+面试整理+进阶书籍,Java实现单链表

目录

  • 链表

      • 单链表示意图:
  • 链表节点定义:

  • 单链表的操作:

    • 1.单链表的打印
  • 2.头插法

  • 3.尾插法

  • 4.任意位置插入

  • 5.查找关键字key是否在单链表中

  • 6.删除第一次出现关键字为key的节点

  • 7.删除所有值为key的节点

  • 8.得到单链表的长度

  • 9.单链表的清空

    • 附上全部代码:
  • **部分检验代码:**

链表

=============================================================

定义:

链表是一种物理存储结构上非连续存储结构,是Java数据结构中一种很基础很常见却也很重要的数据结构

数据元素的逻辑顺序是通过链表中的引用链接次序实现的

思考:如何把一组数据串起来?

对于单链表来说,它是由一个一个节点串起来的,而每一个节点的组成由数值域 (data域) 和下一个节点的引用 (next域) 组成

单链表示意图:

1.不带头节点的单向非循环链表:

在这里插入图片描述

2.带有头节点的单向非循环链表:

在这里插入图片描述

3.带有头节点的单向循环链表:

在这里插入图片描述

由上图,可得:

  • 链表不同于数组,链表是以结点的形式存储,在物理空间上不一定连续

  • 单链表是由节点组成的

  • 链表的每个节点的包含 data (数据)域,next (指针)域,指针域:指向下一个结点的位置

  • 带有头节点的单向非循环链表,头结点是不会发生改变的

而不带头节点的单向非循环链表的头节点可能会发生改变

  • 带有头节点的单向非循环链表,其头节点不可以被删除

  • 链表的头结点不存储数据,只是为了指向链表的开头

接下来的例子以不带头节点的单向非循环链表为例:

链表节点定义:


通过分析,每一个节点都是对象,都有两个属性,一个data,一个next

在这里,我们通过一个类来表示一个结点,在类中声明数据及下一个结点next

//节点类型

class Node{

//Node的两个属性

public int data; //0

public Node next; //null

//提供一个构造方法,实例化对象

public Node(int data){

this.data = data;

this.next = null;

}

}

单链表的操作:


1.单链表的打印

public void print(){

Node cur = this.head;

while(cur != null){

System.out.print(cur.data+" ");

cur = cur.next; //节点后移

}

}

若写成cur.next,则就少打印一个数

在这里插入图片描述

2.头插法

单链表插入的时候,要先绑后边

public void addFist(int data){

Node node = new Node(data);

node.next = this.head;

head = node;

}

头插法执行过程:

在这里插入图片描述

在这里插入图片描述

3.尾插法

public void addLast(int data){

Node node = new Node(data);

if(this.head == null){

this.head = node;

return;

}

Node last = this.head;

while (last.next != null){

last = last.next;

}

last.next = node;

}

尾插法关键的点在于"找尾巴"

在这里插入图片描述

在这里插入图片描述

4.任意位置插入

将第一个位置看成0号下标:

以插入2号位置为例:

  1. 首先定义一个 cur,走index-1步,找到 2 号位置的前一个(重点)

  2. 插入:先连接后边的值,再连接后边的值

node.next = cur.next;

cur.next = node;

  1. 若 index 为0,则相当于一个头插法

  2. 若 index 为 len-1,则相当于一个尾插法

public void addIndex(int index,int data){

Node node = new Node(data);

if(index == 0){

this.addFist(data);

return;

}

if(index == this.len()){

this.addLast(data);

return;

}

//需要找到index位置的前一个节点的地址

Node cur = searchIndex(index);

//插入

node.next = cur.next;

cur.next = node;

}

private Node searchIndex(int index){

//index合法性判定

if(index < 0 || index > this.len()){

throw new RuntimeException(“index位置不合法!”);

}

Node cur = this.head;

while(index-1 != 0){

cur = cur.next;

index–;

}

return cur;

}

在这里插入图片描述

5.查找关键字key是否在单链表中

public boolean contain(int key){

Node cur = this.head;

while (cur != null){

if(cur.data == key){

return true;

}

cur = cur.next;

}

return false;

}

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

public void deleteKey(int key){

if(this.head == null){

return;

}

//删除的是不是头节点

if(this.head.data == key){

this.head = this.head.next;

return;

}

//找到删除节点的前驱

Node tmp = searchTmp(key);

if(tmp == null){

System.out.println(“该节点不存在!”);

return;

}

Node del = tmp.next;

tmp.next = del.next;

}

//找要删除节点的前驱

private Node searchTmp(int key){

Node tmp = this.head;

while(tmp.next != null){

if(tmp.next.data == key){

return tmp;

}

else{

tmp = tmp.next;

}

}

return null;

}

  1. 首先定义一个 tmp,找到要删除节点的前一个位置

  2. 将后一个next覆盖给前一个,即:tmp.next = del.next

在这里插入图片描述

7.删除所有值为key的节点

public void deleteAllKey(int key){

Node tmp = this.head;

Node cur = this.head.next; //代表要删除的节点

while(cur != null){

if(cur.data == key){

tmp.next = cur.next;

cur = cur.next;

}

else {

tmp = cur;

cur = cur.next;

}

}

if(this.head.data == key){

this.head = this.head.next;

}

}

8.得到单链表的长度

public int len(){

int count = 0;

Node cur = this.head;

while (cur != null){

count++;

cur = cur.next;

}

return count;

}

9.单链表的清空

JVM 在回收内存的时候,当该对象没有人在引用它的时候,这个对象才会被回收

public void clear(){

this.head = null;

}

以上是单链表最基础的全部代码

附上全部代码:

//节点类型

class Node{

//Node的两个属性

public int data; //0

public Node next; //null

//提供一个构造方法,实例化对象

public Node(int data){

this.data = data;

this.next = null;

}

}

public class MyLinkedList {

//head 是 MyLinkedList的一个成员属性,代表整个链表的头

public Node head; //保存单链表头节点的引用 值默认为null

//1.打印单链表

public void print(){

Node cur = this.head;

while (cur != null){

System.out.print(cur.data+" ");

cur = cur.next; //节点后移

}

System.out.println();

}

//2.头插法

public void addFist(int data){

Node node = new Node(data);

node.next = this.head;

head = node;

}

//3.尾插法

public void addLast(int data){

Node node = new Node(data);

if(this.head == null){

this.head = node;

return;

}

Node last = this.head;

while (last.next != null){

last = last.next;

}

last.next = node;

}

//4.任意位置插入,第一个数据节点为0号下标

public void addIndex(int index,int data){

Node node = new Node(data);

if(index == 0){

this.addFist(data);

return;

}

if(index == this.len()){
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

分享

这次面试我也做了一些总结,确实还有很多要学的东西。相关面试题也做了整理,可以分享给大家,了解一下面试真题,想进大厂的或者想跳槽的小伙伴不妨好好利用时间来学习。学习的脚步一定不能停止!

薪酬缩水,“裸辞”奋战25天三面美团,交叉面却被吊打,我太难了

Spring Cloud实战

薪酬缩水,“裸辞”奋战25天三面美团,交叉面却被吊打,我太难了

Spring Boot实战

薪酬缩水,“裸辞”奋战25天三面美团,交叉面却被吊打,我太难了

面试题整理(性能优化+微服务+并发编程+开源框架+分布式)
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!**

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

分享

这次面试我也做了一些总结,确实还有很多要学的东西。相关面试题也做了整理,可以分享给大家,了解一下面试真题,想进大厂的或者想跳槽的小伙伴不妨好好利用时间来学习。学习的脚步一定不能停止!

[外链图片转存中…(img-JX58T7JV-1713473684891)]

Spring Cloud实战

[外链图片转存中…(img-3SUu00Ep-1713473684892)]

Spring Boot实战

[外链图片转存中…(img-P8Zq62wH-1713473684892)]

面试题整理(性能优化+微服务+并发编程+开源框架+分布式)
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 29
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值