【数据结构_5】链表(模拟实现以及leetcode上链表相关的题目)

书接上文,继续编写链表的功能

4.链表的中间插入

在链表中,本身是没有下标这样的概念的,不像顺序表,顺序表根据下标访问元素,O(1)复杂度。链表需要遍历之后找到正确的位置才能进行插入,为O(N)复杂度。

但是这件事在JAVA中是个例外,JAVA标准库LinkedList引入了下标概念。

    public int size(){int size =0;for(Node cur = head; cur.next!=null;cur = cur.next){size++;}return size;}//4.中间插入的操作public void add(int index,String value){int size = size();//1.首先判断index是否合法if(index<0 || index >size){throw  new RuntimeException("下标超出范围");}//1.首先要找到index-1的prev节点Node prev = head;//上述代码出现了一个问题:如果是头插,那么就会导致循环无法进去,那么prev是第一个节点,插入的永远是下标为1的地方//*特殊情况需要特殊考虑if(index ==0){addFirst(value);return;}for (int i = 0; i < index-1; i++) {prev = prev.next;}//3.此时进行修改操作Node newNode = new Node(value);newNode.next = prev. next;prev.next = newNode;}
//5.看某个元素是否被包含在链表当中
 public boolean contains(String value){for(Node cur = head;cur.next != null;cur = cur.next){if(cur.value.equals(value)){return true;}}return false;}

//6.找到了就返回index
 public int indexOf(String value){int index =0;for(Node cur = head;cur.next != null;cur = cur.next){if(cur.value.equals(value)){return index;}else {index++;}}return -1;}
//7.根据下标删除

    //7.根据下标删除public void remove( int index){int size = size();//1.首先要判断index的值是否合法if( index <0 || index >=size){throw new RuntimeException("下标越界");}//*要考虑特殊的删除头节点if(index ==0){head = head.next;return ;}//2.其次要找到上一个节点Node prev = head;for (int i = 0; i < index-1; i++) {prev = prev.next;}//3.然后要进行删除操作prev.next = prev.next.next;}
//8.根据值来删除
    public void remove(String value){//还要考虑空链表的情况if(head == null){return;}//有关添加删除操作都要考虑前一个节点 所以每次创建的都是prevNode prev = head;for(;prev!=null;prev= prev.next){if(prev.next!= null&&prev.next.equals(value)){//找到了break;}}//出来之后有两种情况 一种是找到了value 另一种是遍历完了都没有找到valueif(prev == null){return;}else{//找到了,进行删除操作Node cur = prev.next;prev.next = cur.next;}}

//9.全部删除的clear操作

    //9.clear()public void clear(){head = null;}

至此,LinkedList基本写成了

总体:

package LinkedList;//要想实现链表的基本功能,首先要表示链表的一个节点
//对于节点这个类来说,他的本身功能单一,比较简单
//如果高一些get set 方法 ,后续代码就会显得很难看class Node{public String value;//节点保存的值public Node next;//这个节点的下一个元素public Node(String value) {this.value = value;this.next = null;}//当我们创建一个Node的时候,就创建好了链表的头节点,此时链表头节点的值可以确定,且尚未含有下一个节点
}
//这是一个单链表的节点 双向链表还需要一个prev
public class MyLinkedList {//把链表的头节点表示出来,此时整个链表就都能被获取到了//此处不包含傀儡系欸但,head== null 的时候表示空的链表private Node head = null;//1.链表的头插操作public void addFirst(String value){Node newNode = new Node(value);newNode.next =head;head = newNode;//head只是一个引用类型!!!}//2.遍历链表的操作public String toString(){StringBuilder stringBuilder = new StringBuilder();stringBuilder.append("[");for (Node cur = head;cur!= null; cur= cur.next) {stringBuilder.append(cur.value);if(cur.next!= null) {stringBuilder.append(",");}}stringBuilder.append("]");return stringBuilder.toString();}//3.尾插操作public void addLast( String value){//1.首先找到最后一个节点Node tail = head;//*还要考虑特殊的情况if(head == null){Node node = new Node(value);head = node;return;}for (;tail.next!=null; tail = tail.next) {if(tail.next==null){break;}}//此时的tail也就是我们要找的最后一个节点Node node = new Node(value);tail.next = node;node.next = null;}public int size(){int size =0;for(Node cur = head; cur.next!=null;cur = cur.next){size++;}return size;}//4.中间插入的操作public void add(int index,String value){int size = size();//1.首先判断index是否合法if(index<0 || index >size){throw  new RuntimeException("下标超出范围");}//1.首先要找到index-1的prev节点Node prev = head;//上述代码出现了一个问题:如果是头插,那么就会导致循环无法进去,那么prev是第一个节点,插入的永远是下标为1的地方//*特殊情况需要特殊考虑if(index ==0){addFirst(value);return;}for (int i = 0; i < index-1; i++) {prev = prev.next;}//3.此时进行修改操作Node newNode = new Node(value);newNode.next = prev. next;prev.next = newNode;}//5.看某个元素是否被包含在链表当中public boolean contains(String value){for(Node cur = head;cur != null;cur = cur.next){if(cur.value.equals(value)){return true;}}return false;}//6.找到了就返回indexpublic int indexOf(String value){int index =0;for(Node cur = head;cur != null;cur = cur.next){if(cur.value.equals(value)){return index;}else {index++;}}return -1;}//7.根据下标删除public void remove( int index){int size = size();//1.首先要判断index的值是否合法if( index <0 || index >=size){throw new RuntimeException("下标越界");}//*要考虑特殊的删除头节点if(index ==0){head = head.next;return ;}//2.其次要找到上一个节点Node prev = head;for (int i = 0; i < index-1; i++) {prev = prev.next;}//3.然后要进行删除操作prev.next = prev.next.next;}//8.根据值来删除public void remove(String value){//还要考虑空链表的情况if(head == null){return;}//有关添加删除操作都要考虑前一个节点 所以每次创建的都是prevNode prev = head;for(;prev!=null;prev= prev.next){if(prev.next!= null&&prev.next.equals(value)){//找到了break;}}//出来之后有两种情况 一种是找到了value 另一种是遍历完了都没有找到valueif(prev == null){return;}else{//找到了,进行删除操作Node cur = prev.next;prev.next = cur.next;}}//9.clear()public void clear(){head = null;}
}
class Solution {public ListNode removeElements(ListNode head, int val) {//1.首先判断链表是否为空if(head == null){return null;}//2.利用循环删除每一个值为val的元素,但是是从head后面开始删除的!ListNode prev = head;ListNode cur = prev.next;while(cur!=null){if(cur.val == val){//就触发删除操作prev.next = cur.next;//还要将cur进行后置cur = prev.next;}else{prev = cur;cur =cur.next;}}//cur == null 再判定开头的元素if(head.val==val){head = head.next;}return head;}}

1.这道题的要点就在于头节点的删除,如果head=[7,7,7,7],我们就先不管头节点,先把后面值等于val的节点删除,然后循环出来再去考虑头节点。

现在要得到这个链表的翻转链表

思路:分别设置三个引用变量:prev,cur,next。使三者遍历整个链表,按照如下图所示的操作完成链表的翻转。

*为什么一定要设置三个,而不能只使用cur?

因为在完成翻转操作之后,我们还想让循环继续,但是此时cur.next=prev,所以我们要通过next这个引用变量为我们指明前方的道路

也就是说,pev=cur;cur = next; next = next.next;

一直到cur == null,然后跳出循环

class Solution {public ListNode reverseList(ListNode head) {//1.首先判断链表是否为空if(head == null){return null;}   //2.如果链表里只含有一个元素,那么翻转还是不反转没有任何影响if(head.next == null){return head;}//3.来处理一般情况//首先要创建三个引用变量ListNode prev = null;ListNode cur = head;ListNode next = cur.next;//再创建一个新的头节点,待会儿返回ListNode newHead = null;while(cur!=null){next = cur.next;if(next == null){//已经全部完成了newHead = cur;//这个地方不能break,因为下面的操作还需要更新!!!}cur.next = prev;prev = cur;cur = next;}

思路:首先我们可以计算处链表的长度,其次只要将链表的长度/2 之后再遍历我们就可以得到第二个中间节点的值了

class Solution {public ListNode middleNode(ListNode head) {int size = 0;for(ListNode cur = head ; cur!= null;cur = cur.next){size++;}int num = size/2;ListNode cur = head;while(num != 0){num--;cur = cur.next;}return cur;}
}

思路:1.创建新的链表表示最终结构

2.搞两个引用,分别指向两个链表

3.比较这两个引用的值,谁小,就把哪个节点取出来,插入到新链表的末尾,如果这两个引用,有任何一个指向了null,说明该链表就结束了,就把另一个链表剩余的元素都添加到新链表的末尾即可。

代码:

class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {//1.判断list1为空链表的情况if(list1 == null){return list2;}//2。判断list2为空链表的情况if(list2 == null){return list1;}//3.考虑一般情况//为了使后续的插入方便我们首先创建一个傀儡节点以及末尾节点ListNode newHead = new ListNode(0);ListNode tail = newHead;ListNode cur1 = list1;ListNode cur2 = list2;while(cur1!=null && cur2 !=null){if(cur1.val < cur2.val){//cur1比较小 所以把cur1放进来ListNode newNode =cur1;tail.next = newNode;tail = newNode; cur1 = cur1.next;}else{ListNode newNode =cur2;tail.next = newNode;tail = newNode; cur2 = cur2.next;}}//出来的时候,要么cur1还有剩余,要么cur2还有剩余if(cur1 != null){//把剩余的链表给他接上去tail.next = cur1;}if(cur2 != null){tail.next = cur2;}return newHead.next;//不能返回newHead 要返回傀儡节点的下面一个节点}
}

写不动了!明天再见!

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

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

相关文章

C语言的发展史

一、起源 C语言的起源可以追溯到20世纪60年代末期。其前身是BCPL&#xff08;Basic Combined Programming Language&#xff09;语言&#xff0c;由剑桥大学的Martin Richards于1967年在CPL语言的基础上简化而来。1970年&#xff0c;美国贝尔实验室的Ken Thompson以BCPL语言为…

深入解析栈式虚拟机与反向波兰表示法

1.1 什么是虚拟机&#xff1f; 虚拟机&#xff08;Virtual Machine, VM&#xff09;是一种软件实现的计算机系统&#xff0c;提供与物理计算机相类似的环境&#xff0c;但在软件层面运行。虚拟机的存在简化了跨平台兼容性、资源管理以及安全隔离等问题。 1.2 栈式虚拟机的架构…

ubuntu 系统安装Mysql

安装 mysql sudo apt update sudo apt install mysql-server 启动服务 sudo systemctl start mysql 设置为开机自启 sudo systemctl enable mysql 查看服务状态 &#xff08;看到类似“active (running)”的状态信息代表成功&#xff09; sudo systemctl status mysql …

《前端面试题之 CSS篇(第一集)》

目录 1、CSS的盒模型2、CSS选择器及其优先级3、隐藏元素的方法有那些4、px、em、rem的区别及使用场景5、重排、重绘有什么区别6、水平垂直居中的实现7、CSS中可继承与不可继承属性有哪些8、Sass、Less 是什么&#xff1f;为什么要使用他们&#xff1f;9、CSS预处理器/后处理器是…

HTTP:四.HTTP连接

HTTP(Hypertext Transfer Protocol)是一种用于传输超文本数据的应用层协议。它是互联网上最常用的协议,用于在客户端和服务器之间传输数据。HTTP协议通常用于从Web服务器传输网页和文件到客户端浏览器,并支持其他用途,如传输API数据和传输文件。 HTTP连接是指客户端向服务…

opencv 识别运动物体

import cv2 import numpy as npcap cv2.VideoCapture(video.mp4) try:import cv2backSub cv2.createBackgroundSubtractorMOG2() except AttributeError:backSub cv2.bgsegm.createBackgroundSubtractorMOG()#形态学kernel kernel cv2.getStructuringElement(cv2.MORPH_REC…

要查看 ​​指定 Pod 的资源限制(CPU/内存)

要查看 指定 Pod 的资源限制&#xff08;CPU/内存&#xff09;&#xff0c;可以通过以下 kubectl 命令实现&#xff1a; 1. 快速查看某个 Pod 的资源限制 kubectl get pod <pod-name> -o jsonpath{.spec.containers[*].resources} | jq输出示例&#xff1a; {"lim…

信息安全管理与评估广东省2023省赛正式赛题

任务1&#xff1a;网络平台搭建(60分) 题号 网络需求 1 根据网络拓扑图所示&#xff0c;按照IP地址参数表&#xff0c;对DCFW的名称、各接口IP地址进行配置。&#xff08;10分&#xff09; 2 根据网络拓扑图所示&#xff0c;按照IP地址参数表&#xff0c;对DCRS的名称进…

IBM Rational Software Architect安装感受及使用初体验

1 安装感受 最近准备用UML 2.0绘制模型图。在读UML创始人之一Grady Booch写的书《Object-Oriented Analysis and Design with Applications》&#xff08;第3版&#xff09;1时&#xff0c;发现书中用的UML工具之一为IBM Rational Software Architect&#xff08;RSA&#xff…

接听电话,手机靠近耳朵后拿开,挂断电话,设备自动锁屏

目录 一、问题分析/需求分析 二、解决方案 一、问题分析/需求分析 先说一下大致流程: 首先是打电话过程会启动PROXIMITY(接近光传感器)用于监听手机是否到耳边,当手机到耳边时进行灭屏处理,灭屏过程中会调用到锁屏,所以最终会导致锁屏 详细流程分析: 首先根据日志看…

21天Python计划:零障碍学语法(更新完毕)

目录 序号标题链接day1Python下载和开发工具介绍https://blog.csdn.net/XiaoRungen/article/details/146583769?spm1001.2014.3001.5501day2数据类型、字符编码、文件处理https://blog.csdn.net/XiaoRungen/article/details/146603325?spm1011.2415.3001.5331day3基础语法与…

Honor of Kings (S39) 13-win streak

Honor of Kings (S39) 13-win streak S39赛季13连胜&#xff0c;庄周&#xff0c;廉颇硬辅助&#xff0c;对面有回血就先出红莲斗盆&#xff0c;有遇到马克没带净化的&#xff0c;出【冰霜冲击】破他大招 S39&#xff0c;庄周廉颇前排硬辅助全肉全堆血13连胜_哔哩哔哩bilibi…

AI技术实战:从零搭建图像分类系统全流程详解

AI技术实战&#xff1a;从零搭建图像分类系统全流程详解 人工智能学习 https://www.captainbed.cn/ccc 前言 本文将以图像分类任务为切入点&#xff0c;手把手教你完成AI模型从数据准备到工业部署的全链路开发。通过一个完整的Kaggle猫狗分类项目&#xff08;代码兼容PyTorch…

NIPS2024论文 End-to-End Ontology Learning with Large Language Models

文章所谓的端到端本体学习&#xff0c;指的是从输入到目标本体这个完整过程。在很多其他文章中&#xff0c;是把本体学习这个任务肢解了来做的&#xff0c;同样也是肢解了之后评估。 文章号称的贡献&#xff0c;不但对通用本体学习提供所谓的baseline&#xff0c;而且还给出了验…

【NLP】18. Encoder 和 Decoder

1. Encoder 和 Decoder 概述 在序列到序列&#xff08;sequence-to-sequence&#xff0c;简称 seq2seq&#xff09;的模型中&#xff0c;整个系统通常分为两大部分&#xff1a;Encoder&#xff08;编码器&#xff09;和 Decoder&#xff08;解码器&#xff09;。 Encoder&…

Deepseek Bart模型相比Bert的优势

BART&#xff08;Bidirectional and Auto-Regressive Transformers&#xff09;与BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;虽然均基于Transformer架构&#xff0c;但在模型设计、任务适配性和应用场景上存在显著差异。以下是BART…

在人工智能与计算机技术融合的框架下探索高中教育数字化教学模式的创新路径

一、引言 1.1 研究背景 在数字中国战略与《中国教育现代化 2035》的政策导向下&#xff0c;人工智能与计算机技术的深度融合正深刻地重构着教育生态。随着科技的飞速发展&#xff0c;全球范围内的高中教育都面临着培养具备数字化素养人才的紧迫需求&#xff0c;传统的教学模式…

深度探索 C 语言:指针与内存管理的精妙艺术

C 语言作为一门历史悠久且功能强大的编程语言&#xff0c;以其高效的性能和灵活的底层控制能力&#xff0c;在计算机科学领域占据着举足轻重的地位。 指针和内存管理是 C 语言的核心特性&#xff0c;也是其最具挑战性和魅力的部分。深入理解指针与内存管理&#xff0c;不仅能够…

QQ邮箱授权码如何获取 QQ邮箱授权码获取方法介绍

QQ邮箱授权码如何获取 QQ邮箱授权码获取方法介绍 https://app.ali213.net/gl/857287.html

jupyter4.4安装使用

一、chrome谷歌浏览器 1. 安装 1.1 下载地址&#xff1a; 下载地址&#xff1a; https://www.google.cn/intl/zh-CN_ALL/chrome/fallback/ 2 插件markdown-viewer 2.1 下载地址&#xff1a; 下载地址&#xff1a;https://github.com/simov/markdown-viewer/releases 2.2…