数据结构之单链表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.mzph.cn/news/57512.shtml

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

相关文章

24 | 紧跟时代步伐:微服务模式下API测试要怎么做?

微服务架构&#xff08;Microservice Architecture&#xff09; 微服务是一种架构风格。在微服务架构下&#xff0c;一个大型复杂软件系统不再由一个单体组成&#xff0c;而是由一系列相互独立的微服务组成。其中&#xff0c;各个微服务运行在自己的进程中&#xff0c;开发和部…

C# char曲线控件

一、char曲线显示随机数数据 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using Syst…

Windows 转 mac 记录

初次从Windows转mac可能会不适应&#xff0c;建议先看看 【6分钟搞定MacBook】不懂时无所适从&#xff0c;学会后越用越爽&#xff01;_哔哩哔哩_bilibili 我主要是做一些补充记录 1、Windows的右键等于mac的双击触控板、control单击触控板 2、运行中的应用下方会有一个点&…

安卓webview,网页端生成安卓项目(极速生成)教程

安卓webview&#xff0c;网页端生成安卓项目&#xff08;极速生成&#xff09;教程 一&#xff0c;前言 当自己做了一个PC端的页面&#xff0c;也就是前端的页面&#xff0c;或者已经上服的页面&#xff0c;但也想生成一个安卓端供用户使用&#xff0c;本教程详细讲解如何把前…

Spark整合hive的时候出错

Spark整合hive的时候 连接Hdfs不从我hive所在的机器上找&#xff0c;而是去连接我的集群里的另外两台机器 但是我的集群没有开 所以下面就一直在retry 猜测&#xff1a; 出现这个错误的原因可能与core-site.xml和hdfs-site.xml有关&#xff0c;因为这里面配置了集群的nameno…

高等职业学校物联网实训室建设方案

一、概述 1.1专业背景 物联网&#xff08;Internet of Things&#xff09;被称为继计算机、互联网之后世界信息产业第三次浪潮&#xff0c;它并非一个全新的技术领域&#xff0c;而是现代信息技术发展到一定阶段后出现的一种聚合性应用与技术提升&#xff0c;是随着传感网、通…

无涯教程-分类算法 - Python实现函数

为了在Python中实现SVM&#xff0c;无涯教程将从标准库导入开始&#xff0c;如下所示- import numpy as np import matplotlib.pyplot as plt from scipy import stats import seaborn as sns; sns.set() 接下来&#xff0c;从sklearn.dataset.sample_generator创建具有线性可…

Ceph源码解析:PG peering

集群中的设备异常(异常OSD的添加删除操作)&#xff0c;会导致PG的各个副本间出现数据的不一致现象&#xff0c;这时就需要进行数据的恢复&#xff0c;让所有的副本都达到一致的状态。 一、OSD的故障和处理办法&#xff1a; 1. OSD的故障种类&#xff1a; 故障A&#xff1a;一…

【微服务部署】01-Kubernetes部署流程

文章目录 部署1. Kubernetes是什么2. Kubernetes的优势3. 环境搭建4. 应用部署 部署 1. Kubernetes是什么 Kubernetes是一个用于自动部署、扩展和管理容器化应用程序的开源系统 2. Kubernetes的优势 自动化容器部署资源管理与容器调度服务注册发现与负载均衡内置配置与秘钥…

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

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

Gitlab设置中文

1. 打开设置 2.选择首选项Preferences 3. 下滑选择本地化选项Localization&#xff0c;设置简体中文&#xff0c;然后保存更改save changes。刷新网页即可。

Rabbitmq的Federation Exchange

(broker 北京 ) &#xff0c; (broker 深圳 ) 彼此之间相距甚远&#xff0c;网络延迟是一个不得不面对的问题。有一个在北京的业务(Client 北京 ) 需要连接 (broker 北京 ) &#xff0c;向其中的交换器 exchangeA 发送消息&#xff0c;此时的网络延迟很小&#xff0c;(C…

开源文库系统moredoc

什么是 moredoc &#xff1f; moredoc 中文名 魔豆文库&#xff0c;是基于 golang 开发的类似百度文库、新浪爱问文库的开源文库系统&#xff0c;支持 TXT、PDF、EPUB、MOBI、Office 等格式文档的在线预览与管理&#xff0c;为 dochub 文库(github, gitee &#xff09;的重构版…

k8s的交付与部署案例操作

一 k8s的概念 1.1 k8s k8s是一个轻量级的&#xff0c;用于管理容器化应用和服务的平台。通过k8s能够进行应用的自动化部署和扩容缩容。 1.2 k8s核心部分 1.prod: 最小的部署单元&#xff1b;一组容器的集合&#xff1b;共享网络&#xff1b;生命周期是短暂的&#xff1b; …

【c语言】结构体内存对齐,位段,枚举,联合

之前学完结构体&#xff0c;有没有对结构体的大小会很疑惑呢&#xff1f;&#xff1f;其实结构体在内存中存储时会存在内存对齐&#xff0c;捎带讲讲位段&#xff0c;枚举&#xff0c;和联合&#xff0c;跟着小张一起学习吧 结构体内存对齐 结构体的对齐规则: 第一个成员在与结…

kafka复习:(22)一个分区只能被消费者组中的一个消费者消费吗?

默认情况下&#xff0c;一个分区只能被消费者组中的一个消费者消费。但可以自定义PartitionAssignor来打破这个限制。 一、自定义PartitionAssignor. package com.cisdi.dsp.modules.metaAnalysis.rest.kafka2023;import org.apache.kafka.clients.consumer.internals.Abstrac…

【BUG事务内消息发送】事务内消息发送,事务还未结束,消息发送已被消费,查无数据怎么解决?

问题描述 在一个事务内完成插入操作&#xff0c;通过MQ异步通知其他微服务进行事件处理。 由于是在事务内发送&#xff0c;其他服务消费消息&#xff0c;查询数据时还不存在如何解决呢&#xff1f; 解决方案 通过spring-tx包的TransactionSynchronizationManager事务管理器解…

LeetCode 热题 100(七):105. 从前序与中序遍历序列构造二叉树、14. 二叉树展开为链表

题目一&#xff1a; 105. 从前序与中序遍历序列构造二叉树https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ 思路&#xff1a;依据前序遍历的根左右和中序遍历的左根右&#xff0c; 且根左长度&#xff1d;左根 代码&#xff1a; …

C#搭建WebSocket服务实现通讯

在学习使用websocket之前我们先了解一下websocket&#xff1a; WebSocket是一种在单个TCP连接上进行全双工通信的通信协议。与HTTP协议不同&#xff0c;它允许服务器主动向客户端发送数据&#xff0c;而不需要客户端明确地请求。这使得WebSocket非常适合需要实时或持续通信的应…

纯 CSS 开关切换按钮

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>纯 CSS 开关切换按钮</title><style>html {font-size: 62.5%;}body {background-color: #1848a0;}.wrapper {position: absolute;left: …