Java链表数据结构及其简单使用方法解析
作者:??行百里er?? 发布时间:2022-11-20 23:42:53
认识链表结构
单向链表
单链表在内存中的表示:
可以看到,一个链表的节点包含数据域和指向下一个节点的引用,链表最后一个节点指向null(空区域)。
我们可以根据这一定义,用Java语言表示一下单向链表的结构:
public class Node {
public int value;
public Node next;
public Node(int value) {
this.value = value;
}
}
在链表的结构中,有数据域value,以及一个指向下一个节点的引用next。
TIP:这里的value还可以定义成泛型的。
双向链表
我们再来看一下双向链表的结构:
双向链表中的节点有数值域,和指向它前一个节点的引用以及指向它后一个节点的引用,据此我们可以定义出
双向链表的结构:
public class DoubleNode {
public int value;
public DoubleNode pre;
public DoubleNode next;
public DoubleNode(int value) {
this.value = value;
}
}
加深对链表结构的理解
实现单向和双向链表的反转
说明:
对于一个链表如图所示:
反转的意思是,将原来链表上的节点指针指向反转,原来的指向是:a -> b -> c -> d -> null,变成现在的指向:d -> c -> b -> a -> null,
即反转后的结构如图所示:
这个题目不难,我们转换一下指针的指向就行了。
设计这样一个函数,函数的过程是调整链表各节点的指针指向,那么这个函数的要素有:
返回值是链表的新的头结点,这样能保证函数执行完,原链表变成一个有新的头结点的链表
需要传入一个链表,用头结点表示
解题技巧:定义两个Node引用辅助我们反转指针指向。
代码实现:
public static Node reverseNode(Node head) {
Node pre = null;
Node next = null;
//最终让head指向null
while (head != null) {
next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}
我们来模拟一下这个函数的执行过程。
链表原始状态:
方法开始执行,此时 head.next
不为空,所以,执行如下步骤:
next = head.next:让next指向head(当前节点)的下一个节点,即b
head.next = pre:让当前节点的下一个节点指向pre,即null
此时当前节点从原来指向b,改为指向null。
pre = head:让pre指向当前节点
head = next:让当前节点指向next,相当于移动head节点,直到将head节点移动到原来tail节点的位置
第一次循环执行结束,此时 head
为b,不是null,所以继续循环,执行流程:
此时 head
为c,不是null,所以继续循环,执行流程如下:
同理,此时 head 为d,不是null,继续循环:
这是就完成了单链表的反转步骤。
有了单链表反转的经验,我们很容易就能实现双向链表的反转,代码如下:
public DoubleNode reverseDoubleNode(DoubleNode head) {
DoubleNode pre = null;
DoubleNode next = null;
while (head != null) {
next = head.next;
//操作(移动)当前节点
head.next = pre;
head.pre = next;
pre = head;
head = next;
}
return pre;
}
实现把链表中给定的值都删除
题如:给定一个单链表头节点head,以及一个整数,要求把链表中值为给定整数的节点都删除。
实现思路:
要实现的函数需要给我传一个头节点以及给定的数值,头节点确定链表。func(Node head, int num)。
函数给不给返回值,返回值是什么?试想,针对链表
3 -> 5 -> 4 -> 3 -> 4 -> 5
,假如要删除4,那么新链表就是3 -> 5-> 3 -> 5
,头节点仍然是原来的节点3;而如果要删除值为3的节点呢,删除后就是5 -> 4 -> 4 -> 5
,头节点变了。因此,我们要设计的这个函数需要返回新链表的头节点。上述分析得知,需要返回新链表的头节点,因此也就是要返回第一个不是给定值的节点(因为给定值的节点都要被删除掉)。
//head移动到第一个不需要删除的位置:边界条件
while (head != null) {
if (head.value != num) {
break;
}
//head右移
head = head.next;
}
//跳出循环之后,head的情况:
//1. head = null,这种情况是链表中的值全部是给定值,全删了
//2. head != null
// 中间操作
//最终返回head:第一个不是给定值的节点
return head;
head移动到第一个不需要删除的位置后,head若为null,表示所有节点都删除了,直接返回就可以了;若head不为null,借助两个辅助变量Node pre和cur,从head处开始往next走,遇到给定值就跳过。
Node pre = head;
Node cur = head;
while (cur != null) {
if (cur.value == num) {
pre.next = cur.next;
} else {
pre = cur;
}
cur = cur.next;
}
这一执行过程图解如下:
通过上述分析,写出完整实现代码:
public static Node remove (Node head, int num) {
while (head != null) {
if (head.value != num) {
break;
}
head = head.next;
}
Node pre = head;
Node cur = head;
while (cur != null) {
if (cur.value == num) {
pre.next = cur.next;
} else {
pre = cur;
}
cur = cur.next;
}
return head;
}
小结
针对链表这种数据结构进行了一些简单的分析,通过两个例子熟悉了链表的结构。
针对链表的操作,需要注意的就是指针指向以及边界问题,后续关于链表的算法还会遇到。
来源:https://juejin.cn/post/7116350143703547935
猜你喜欢
- 一、算法原理插入排序法:所谓插入排序法乃是将一个数目插入该占据的位置。假设我们输入的是 “53,27,36,15,69, 42”
- Weblogic部署war找不到spring配置文件我有一个web工程在Tomcat7下部署没有问题,可是移植到Weblogic10上出现如
- 关于这个系列里的问题,每个学Java的人都应该搞懂。当然,若是仅仅学Java玩玩就无所谓了。若是你以为本人现已逾越初学者了,却不很懂这些问题
- mybatis-plus作为mybatis的增强工具,简化了开发中的数据库操作。一旦遇到left join或right join的左右连接,
- 1.在res上面右键->New->Android resource directory2.点击之后,出现下图Resource t
- 关于用户token处理到的坑当采用前后台完全分离,以微服务架构的搭建时。在搭建微服务过程中,由于每个服务都是独立的应用,这样就会造成一个统一
- 在不用Maven的时候,比如说以前我们用Ant构建项目,在项目目录下,往往会看到一个名为/lib的子目录,那里存放着各类第三方依赖jar文件
- 前言Spring Data Jpa框架的目标是显著减少实现各种持久性存储的数据访问层所需的样板代码量。Spring Data Jpa存储库抽
- Lombok有什么用在我们实体Bean中有大量的Getter/Setter方法以及toString, hashCode等可能不会用到,但是某
- Stream简化元素计算一、接口设计从Java1.8开始提出了Stream流的概念,侧重对于源数据计算能力的封装,并且支持序列与并行两种操作
- (注意:本文基于JDK1.8) 前言Vector是线程安全的动态数组类,提供4个创建Vector对象的构造方法,接下来我们逐个分析
- 这篇文章介绍了Java+Nginx实现POP、IMAP、SMTP邮箱代理服务,我们本次使用的环境为Centos7下,java程序我们通过ec
- 一、前言拷贝这个词想必大家都很熟悉,在工作中经常需要拷贝一份文件作为副本。拷贝的好处也很明显,相较于新建来说,可以节省很大的工作量。在Jav
-   考虑到直接讲实现一个类Task库思维有点跳跃,所以本节主要讲解Async/Await的本质作用(解决
- java 闰年判断前言:给定一个年份,判断这一年是不是闰年。当以下情况之一满足时,这一年是闰年:1. 年份是4的倍数而不是100的倍数;2.
- 在构建RESTful数据服务过程中,我们定义了controller、repositories,并用一些注解修饰它们,但是到现在为止我们还没执
- 本文实例讲述了Java使用Jdbc连接Oracle执行简单查询操作。分享给大家供大家参考,具体如下:Java Jdbc 连接 Oracle
- 前一段时间粗略看了一下《深入Java虚拟机 第二版》,可能是因为工作才一年的原因吧,看着十分的吃力。毕竟如果具体到细节的话,Java虚拟机涉
- 使用Java的方式配置Spring我们现在要完全不使用Spring的xml配置,全权使用Java来配置Spring!JavaConfig是S
- 前言最近遇到一个Jvm old过高的案例,现象是一个站点的jvm old区过高,分析原因是,原来的设计方案有问题,给前端返回的数据里面包含了