数据结构之单链表java实现

基本概念

链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中指针链接次序实现的。和数组相比较,链表不需要指定大小,也不需要连续的地址。
单链表的基本设计思维是,利用结构体的设置,额外开辟一个空间去做指针,指向下一个结点。
在这里插入图片描述
其中,DATA是需要存储的数据元素,可以为任何数据格式,可以是数组,可以是int,还可以是结构体。
NEXT作为一个空指针,其代表了一个可以指向的区域,通常是用来指向下一个结点,链表尾部NEXT指向NULL(空),因为尾部没有任何可以指向的空间了。

创建结点

private static class Node<E> {private E item; private Node<E> next;Node(E element,Node<E> next){item = element;this.next = next;}
}
创建接口```java
public interface BaseTab<T> {/*** 空置链表*/public void clear();/*** 判断链表是否为空* @return true 为空*/public boolean isEmpty();//获取链表中的元素个数public int length();//获取并返回线性表中的第i个元素public T get(int i);//添加一个元素public void insert(T t);//向第i个元素之前插入一个元素public void insert(int i,T t);//删除并返回第i个元素public T remove(int i);//返回指定元素的序号,若不存在返回-1public int indexOf(T t);
}

实现全部功能

public class SingleLinkedList<E> implements BaseTab<E>{private Node<E> mHeader; //链表头部结点,头部结点不存储数据,只存储nextprivate int size = 0; //记录链表长度public SingleLinkedList(){}@Overridepublic void clear() {mHeader.next = null;size = 0;}@Overridepublic boolean isEmpty() {return size == 0;}@Overridepublic int length() {return size;}@Overridepublic E get(int index) {Node<E> node = mHeader;//从Header开始循环for(int i = 0;i < index;i++){node = node.next;}return node.item;}@Overridepublic void insert(E data) {if(mHeader == null){mHeader = new Node<E>(data,null);size++;return;}Node<E> lastNode = mHeader;while (lastNode.next != null){ //通过循环找到链表的尾部lastNode = lastNode.next;}lastNode.next = new Node<>(data,null);size++;}@Overridepublic void insert(int index, E data) {//创建新的结点用来存放数据if(mHeader == null){mHeader = new Node<E>(data,null);size++;return;}Node<E> newNode = new Node<E>(data,null);Node<E> preNode = mHeader;for(int i = 0;i <= index -1;i++){ //循环找到index位置的前一个结点preNode = mHeader.next;}newNode.next = preNode.next;preNode.next = newNode;size++;}/*** 打印出链表所有数据*/public void printAll(){Node<E> node = mHeader;while (node.next != null){System.out.println(node.item);node = node.next;}System.out.println(node.item);}@Overridepublic E remove(int index) {//1.找到指定位置的前一个NodeNode<E> preNode = mHeader;for(int i = 0; i < index -1;i++){preNode = preNode.next;}//需要被删除的NodeNode<E> removeNode = preNode.next;preNode.next = removeNode.next;size--;return removeNode.item;}@Overridepublic int indexOf(E data) {Node node = mHeader;for(int i = 0;i < size;i++){if(node.item.equals(data)){return i;} else {node = node.next;}}return -1;}private static class Node<E> {private E item;private Node<E> next;Node(E element,Node<E> next){item = element;this.next = next;}}
}

反转链表

链表反转是一道比较常见的面试题
eg:链表中输入0,1,2,3,4,输出 4,3,2,1,0
在这里插入图片描述
实现一个结点:

public class Node<T> {T data; //数据Node<T> next; //指向下一个结点public Node(T value){data = value;}
}

从结点的结构上面来说,我们需要修改的是next,将next由指向下一个改成指向上一个。
链表全部反转,那就需要从尾部或者头部开始,从尾部开始的话,使用递归的思想。

    public static <T> Node<T> reversalLink(Node<T> head){//主要是通过head.next == null 找出最后面的一个结点if(head == null || head.next == null) return head;//通过递归找到最后的一个作为Head//递归执行顺序是4,3,2,1,0Node<T> revHead = reversalLink(head.next);//调整指针//eg:执行到3时需要做以下操作//1.4的next应该是3,当head = 3时, 目前head.next = 4 4.next = head,就将4的下一个结点指向3head.next.next = head;//执行上上一步后,3->4,4->3,现在需要将3->4断开head.next = null;return revHead;}public static void main(String[] args) {Node<Integer> head = new Node<>(0);Node<Integer> node1 = new Node<>(1);Node<Integer> node2 = new Node<>(2);Node<Integer> node3 = new Node<>(3);Node<Integer> node4 = new Node<>(4);head.next = node1;node1.next = node2;node2.next = node3;node3.next = node4;//反转前Node<Integer> node = head;while (node != null){System.out.print(node.data + " ");node = node.next;}System.out.println("");System.out.println("-----反转后-------");Node<Integer> revHead = reversalLink(head);while (revHead != null){System.out.print(revHead.data + " ");revHead = revHead.next;}}

从链表头部开始
在这里插入图片描述
思路就如上面所画,从header开始,拆成两个链表

    public static <T> Node<T> reversalLink1(Node<T> head){Node<T> preNode = null;Node<T> curNode = head;while (curNode != null){Node<T> nextNode = curNode.next;curNode.next = preNode;preNode = curNode;curNode = nextNode;}return preNode;}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

javacv基础02-调用本机摄像头并预览摄像头图像画面视频

引入架包&#xff1a; <dependency><groupId>org.openpnp</groupId><artifactId>opencv</artifactId><version>4.5.5-1</version></dependency><dependency><groupId>org.bytedeco</groupId><artifactId…

镜之Json Compare Diff

前言 “镜” 寓意是凡事都有两面性,Json 对比也不例外! 因公司业务功能当中有一个履历的功能,它有多个版本的 JSON 数据需要对比出每个版本的不同差异节点并且将差异放置在一个新的 JSON 当中原有结构不能变动,差异节点使用数组对象的形式存储,前端点击标红即可显示多个版本的节…

Python绘图系统9:新建绘图类型控件,实现混合类型图表

文章目录 绘图类型控件改造AxisList更改绘图逻辑源代码 Python绘图系统&#xff1a; &#x1f4c8;从0开始实现一个三维绘图系统自定义控件&#xff1a;坐标设置控件&#x1f4c9;坐标列表控件&#x1f4c9;支持多组数据的绘图系统图表类型和风格&#xff1a;散点图和条形图&a…

春秋云镜 :CVE-2020-21650(MyuCMS后台rce)

一、题目 靶标介绍&#xff1a; MyuCMS开源内容管理系统,采用ThinkPHP开发而成的社区商城聚合&#xff0c;插件&#xff0c;模板&#xff0c;轻便快捷容易扩展 其2.2版本中admin.php/config/add方法存在任意命令执行漏洞. 进入题目&#xff1a; exp&#xff1a; url/index.p…

OpenGL精简案例一

文章目录 案例一 绘制点线面定义Renderer顶点着色器片段着色器内置的特殊变量 应用场景工具ShaderHelper工具 TextResourceReader效果图如下 结论 案例一 绘制点线面 定义Renderer import android.content.Context; import android.opengl.GLES20; import android.opengl.GLSu…

基于空洞卷积DCNN与长短期时间记忆模型LSTM的dcnn-lstm的回归预测模型

周末的时候有时间鼓捣的一个小实践&#xff0c;主要就是做的多因子回归预测的任务&#xff0c;关于时序数据建模和回归预测建模我的专栏和系列博文里面已经有了非常详细的介绍了&#xff0c;这里就不再多加赘述了&#xff0c;这里主要是一个模型融合的实践&#xff0c;这里的数…

Hbase-技术文档-java.net.UnknownHostException: 不知道这样的主机。 (e64682f1b276)

问题描述&#xff1a; 在使用spring-boot操作habse的时候&#xff0c;在对habse进行操作的时候出现这个问题。。 报错信息如下&#xff1a; 第一段报错&#xff1a; 第二段报错&#xff1a; java.net.UnknownHostException: e64682f1b276 问题定位解读&#xff1a; 错误 ja…

Java 体系性能优化工具

Java 体系性能优化 目录概述需求&#xff1a; 设计思路实现思路分析1.oom 异常来说&#xff1a;2.visualvm3.Arthas4.JProfiler &#xff08;全面&#xff09;5.jmeter 特有 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect…

去除wps段落柄,删除空白页

如图&#xff0c;有一个段落柄在左端&#xff0c;无法删除&#xff0c;只能编辑。 导致本来是8页内容&#xff0c;现在是9页&#xff0c;多了一空白页 后面新建一个空白页&#xff0c;发现默认会自带一个段落柄&#xff0c;所以有可能这个段落柄是不能消除的&#xff0c;那么如…

【从零开始学习JAVA | 第四十六篇】处理请求参数

前言&#xff1a; 在我们之前的学习中&#xff0c;我们已经基本学习完了JAVA的基础内容&#xff0c;从今天开始我们就逐渐进入到JAVA的时间&#xff0c;在这一大篇章&#xff0c;我们将对前后端有一个基本的认识&#xff0c;并要学习如何成为一名合格的后端工程师。今天我们介绍…

记一种不错的缓存设计思路

之前与同事讨论接口性能问题时听他介绍了一种缓存设计思路&#xff0c;觉得不错&#xff0c;做个记录供以后参考。 场景 假设有个以下格式的接口&#xff1a; GET /api?keys{key1,key2,key3,...}&types{1,2,3,...} 其中 keys 是业务主键列表&#xff0c;types 是想要取到的…

数据库第十七课-------ETL任务调度系统的安装和使用

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…