数据结构之单链表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.rhkb.cn/news/119047.html

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

相关文章

滑动窗口实例5(水果成篮)

题目&#xff1a; 你正在探访一家农场&#xff0c;农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示&#xff0c;其中 fruits[i] 是第 i 棵树上的水果 种类 。 你想要尽可能多地收集水果。然而&#xff0c;农场的主人设定了一些严格的规矩&#xff0c;你必须按…

垃圾回收 - 引用计数法

GC原本是一种“释放怎么都无法被引用的对象的机制”。那么人们自然而然就会想到&#xff0c;可以让所有对象事先记录下“有多少程序引用了自己”。让各对象知道自己的“人气指数”&#xff0c;从而让没有人气的对象自己消失&#xff0c;这就是引用计数法。 1、计数器 计数器表…

使用MATLAB解算炼油厂的选址

背景 记得有一年的数据建模大赛&#xff0c;试题是炼油厂的选址&#xff0c;最后我们采用MATLAB编写&#xff08;复制&#xff09;蒙特卡洛算法&#xff0c;还到了省级一等奖&#xff0c;这里把仅有一些记忆和材料&#xff0c;放到这里来&#xff0c;用来纪念消失的青春。 本…

selenium可以编写自动化测试脚本吗?

Selenium可以用于编写自动化测试脚本&#xff0c;它提供了许多工具和API&#xff0c;可以与浏览器交互&#xff0c;模拟用户操作&#xff0c;检查网页的各个方面。下面是一些步骤&#xff0c;可以帮助你编写Selenium自动化测试脚本。 1、安装Selenium库和浏览器驱动程序 首先…

Redis布隆过滤器原理

其实布隆过滤器本质上要解决的问题&#xff0c;就是防止很多没有意义的、恶意的请求穿透Redis&#xff08;因为Redis中没有数据&#xff09;直接打入到DB。它是Redis中的一个modules&#xff0c;其实可以理解为一个插件&#xff0c;用来拓展实现额外的功能。 可以简单理解布隆…

Educational Codeforces Round 154 (Rated for Div. 2)

Educational Codeforces Round 154 (Rated for Div. 2) A. Prime Deletion 思路&#xff1a; 因为1到9每个数字都有&#xff0c;所以随便判断也质素即可 代码 #include<bits/stdc.h> using namespace std; #define int long long #define rep(i,a,n) for(int ia;i<…

数学建模-点评笔记 9月3日

1.摘要&#xff1a;关键方法和结论&#xff08;精炼的语言&#xff09;要说明&#xff0c;方法的合理性和意义也可以说明。 评委先通过摘要筛选&#xff08;第一轮&#xff09; 2.时间序列找异常值除了3西格玛还有针对时间序列更合适寻找的方法 3.模型的优缺点要写的详细一点…

vue3 页面显示中文,分页显示中文

vue3 分页默认为英文 &#xff0c;但想要中文显示 那么在App.vue中的代码为三步即可&#xff0c;引入中文&#xff0c;声明中文 &#xff0c;绑定中文&#xff1b; 1. import zhCn from element-plus/es/locale/lang/zh-cn&#xff1b; 2. let locale zhCn; 3. :locale&q…

Snipaste_2023-08-22_16-09-41.jpg

原因 cd 目录名 (想要补全的时候出现以下错误) cd /o-bash: cannot create temp file for here-document: No space left on device解决方案 可以使用df -h命令查看磁盘空间的使用情况,删除一些不必要的文件或调整其他文件的存储位置来释放空间,或者还可以考虑扩大磁盘容量 df …

数据结构1 -- leetcode练习

三. 练习 3.1 时间复杂度 用函数 f ( n ) f(n) f(n) 表示算法效率与数据规模的关系&#xff0c;假设每次解决问题需要 1 微秒&#xff08; 1 0 − 6 10^{-6} 10−6 秒&#xff09;&#xff0c;进行估算&#xff1a; 如果 f ( n ) n 2 f(n) n^2 f(n)n2 那么 1 秒能解决多…

PHP NBA球迷俱乐部系统Dreamweaver开发mysql数据库web结构php编程计算机网页

一、源码特点 PHP NBA球迷俱乐部系统是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 基于PHP的NBA球迷俱乐部 二、功能介绍 1、前台主要功能&#xff1a; 系统首页 网站介…

2023_Spark_实验一:Windows中基础环境安装

Ⅰ、WINDOWS中安装JDK1.8 一、下载安装包 链接&#xff1a;百度网盘 请输入提取码 所在文件夹&#xff1a;根目录或者大数据必备工具--》开发工具(前端后端)--》后端 下载文件名称&#xff1a;jdk-8u191-windows-x64.exe 二、安装JDK 1.现在转到下载的exe文件可用的文件夹&…

从传统到智能化:汽车内部通信的安全挑战与SecOC解决方案

01/需求背景 Demand background 在传统的汽车电子结构中&#xff0c;车内的电控单元&#xff08;ECU&#xff09;数量和复杂性受到限制&#xff0c;通信带宽也受到限制。因此&#xff0c;人们普遍认为车内各个ECU之间的通信是可靠的。只要ECU节点接收到相应的消息&#xff0c…

实际并行workers数量不等于postgresql.conf中设置的max_parallel_workers_per_gather数量

1 前言 本文件的源码来自PostgreSQL 14.5&#xff0c;其它版本略有不同并行workers并不能显箸提升性能。个人不建议使用并行worker进程&#xff0c;大多数情况下采用postgresql.conf默认配置即可。 PostgreSQL的并行workers是由compute_parallel_worker函数决定的&#xff0c…

【人工智能】—_线性分类器、感知机、损失函数的选取、最小二乘法分类、模型复杂性和过度拟合、规范化

文章目录 Linear predictions 线性预测分类线性分类器感知机感知机学习策略损失函数的选取距离的计算 最小二乘法分类求解最小二乘分类矩阵解法一般线性分类模型复杂性和过度拟合训练误差测试误差泛化误差复杂度与过拟合规范化 Linear predictions 线性预测 分类 从具有有限离…

MySQL-数据类型

MySQL-数据类型 数值类型bittinyintfloatdecimal 字符串和文本类型charvarcharblobtext 日期和时间类型enum-枚举类型set-集合类型 数值类型 数据类型说明bit(M)位类型。M指定位数&#xff0c;默认值为1&#xff0c;范围1-64.tinyint [unsigned]带符号范围:-128 - 127&#xf…

JavaScript 生成 16: 9 宽高比

这篇文章只是对 for 循环一个简单应用&#xff0c;没有什么知识含量。 可以跳过这篇文章。 只是我用来保存一下我的代码&#xff0c;保存在本地我嫌碍眼&#xff0c;总想把他删了。 正文部分 公式&#xff1a;其中 width 表示宽度&#xff0c;height 表示高度 16 9 w i d t…

【微服务部署】一、使用docker-compose部署Jenkins、SonarQube、PostgreSQL

一、安装 1、编写docker-compose部署Postgres、SonarQube、Jenkins的yml文件jenkins-compose.yml Postgres&#xff1a;作为SonarQube的数据库存储SonarQube&#xff1a;代码质量检查Jenkins&#xff1a;jenkins/jenkins:lts镜像&#xff0c;jenkinsci/blueocean镜像缺少node…

22.3D等距社交媒体菜单的悬停特效

效果 源码 <!doctype html> <html><head><meta charset="utf-8"><title>CSS Isometric Social Media Menu</title><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.…

Vue框架--理解MVVM

我们知道&#xff0c;MVVM是Model-View-ViewModel的简写。它本质上就是MVC的改进版。我们看看MVVM的模型架构&#xff0c;如下所示: 架构理解与实例