LinkedList概念+MyLinkedList的实现

文章目录

  • LinkedList笔记
    • 一、 LinkedList
      • 1.概念
      • 2.LinkedList的构造方法
      • 3.LinkedList的遍历
    • 二、MyLinkedList的实现
      • 1.定义内部类
      • 2.打印链表、求链表长度、判断是否包含关键字
      • 3. 头插法和尾插法
      • 4.在任意位置插入
      • 5.删除结点
      • 6.清空链表


LinkedList笔记


一、 LinkedList

1.概念

LinkedList的底层是一个双向链表
在这里插入图片描述

  • 在插入和删除时,不用挪动元素
  • 在获取尾部结点时,不需要遍历获取,直接利用last结点

2.LinkedList的构造方法

  • 分为无参构造和有参构造
    在这里插入图片描述

有参:使用其他集合容器中元素构造List
在构造LinkedList的时候,传递的参数的类型要满足指定泛型的上界,同时要实现Collection接口

3.LinkedList的遍历

分别用重写的print方法、foreach、迭代器进行遍历

 public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("hello");
        linkedList.add("world");
        linkedList.add("!");
        linkedList.add("?");
        linkedList.add("|");
        System.out.println(linkedList);
        System.out.println("-----------");
        for (String x:linkedList) {
            System.out.print(x+" ");
        }
        System.out.println();
        System.out.println("-----------");
        //使用迭代器遍历-正向遍历
        ListIterator<String> it = linkedList.listIterator();
        while (it.hasNext()){
            System.out.print(it.next()+" ");
        }
        System.out.println();
        System.out.println("===========");

        ListIterator<String> rit = linkedList.listIterator(linkedList.size());
        while (rit.hasPrevious()){
            System.out.print(rit.previous()+" ");
        }

        //使用迭代器遍历-反向遍历
    }

二、MyLinkedList的实现

1.定义内部类

与单链表不同的是,双链表的结点新增了prev域

public class MyLinkedList {
    static class ListNode{
        public int val;
        public ListNode prev;//前驱
        public ListNode next;//后继

        public ListNode(int val) {//构造方法
            this.val = val;
        }
    }
    public ListNode head;//定义头结点
    public ListNode last;//定义尾结点

1.在内部类中定义结点的元素
2.定义构造器
3.创建头/尾结点

2.打印链表、求链表长度、判断是否包含关键字

与单链表的形式相同

 public void  disPlay(){
        ListNode cur = head;
        while (cur!=null){ 
            System.out.print(cur.val+" ");
            cur = cur.next;
        }
        System.out.println();
    }

    /**
     *求链表长度
     * @return int
     */
    public int size(){
        ListNode cur = head;
        int count = 0;
        while (cur!=null){
            count++;
            cur = cur.next;
        }
        return count;
    }

    /**
     * 查看在链表中是否包含关键字key
     * @param key
     * @return
     */
    public boolean contains(int key){
        ListNode cur = head;
        while (cur != null){
            if (cur.val == key){
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

3. 头插法和尾插法

在这里插入图片描述

    /**
     * 头插法
     * o(1)
     * @param data
     */
    public void addFirst(int data){
        ListNode node = new ListNode(data);
        if (head ==null){
            head = node;
            last = node;
        }else {
            node.next = head;
            head.prev = node;
            head = node;//头结点前移
        }
    }

    /**
     * 尾插法o(1)
     */
    public void addLast(int data){
        ListNode node = new ListNode(data);
        if(head==null){
          head = node;
          last = node;
        }else{
            last.next = node;
            node.prev = last;
            last = node;
        }
    }  

因为尾插的时候有last结点,不用进行尾结点的遍历查找
所以双链表尾插的时间复杂度是 o(1)

4.在任意位置插入

在这里插入图片描述

  public void addIndex(int index, int data) {

        if (index < 0 || index > size()) {//判断索引是否超出
           return;
        }
        if (index == 0) {//利用头插
            addFirst(data);
            return;
        }
        if (index == size()) {//利用尾插
            addLast(data);
            return;
        }
        ListNode node = new ListNode(data);
        ListNode cur = head;
        while (index!=0){//找到索引的位置
            cur = cur.next;
            index--;
        }
        node.next = cur;
        cur.prev.next = node;
        node.prev = cur.prev;
        cur.prev = node;
    }

1.先判断索引下标是否溢出
2.如果索引是开头或者末尾的位置,调用写好的头插法和尾插法
3.通过遍历找到索引的位置cur
4.将cur插入链表中

  • 先改变node的next域,
  • 将node与cur相连 将cur的前驱的next域,改为node,
  • 将node与cur的前一个结点相连
  • 将node前驱改为cur前驱的地址 将cur的前驱改为node的地址值

5.删除结点

在这里插入图片描述

    public void remove(int key) {
        ListNode cur = head;
        while (cur != null) {
            if (cur.val == key) {
                if (cur == head) {//删的是头的情况
                    head = head.next;
                    if (head!=null){//如果只有一个结点,移动后前驱不需要置空
                        head.prev = null;//head的前驱置为空
                    }

                } else {//删除中间或者尾部
                    cur.prev.next = cur.next;
                    if (cur == last) {//如果是尾部
                        last = last.prev;
                    } else {//删除的是中间
                        cur.next.prev = cur.prev;
                    }
                }
                return;
            }
            cur = cur.next;
        }
    }

1.通过遍历找到值等于key的结点
2.如果要删的是头结点,头结点向后移动一位。如果移动后的头结点不为空,将此时头结点的前驱置为空
3.如果要删除的cur是尾结点,将cur前驱的地址值指向cur的下一个地址,将last向前移动一位
4.如果要删除的是中间结点,将cur前驱的地址值指向cur的下一个地址,将cur后继的前驱指向cur的前驱

6.清空链表

在这里插入图片描述

 public void clear() {
        ListNode cur = head;
        while (cur != null) {
            ListNode curNext = cur.next;
            cur.next = null;
            cur.prev = null;
            cur = curNext;
        }
        head = null;
        last = null;
    }

1.遍历链表,用curNext记录cur的下一个结点
2.将cur的前驱和后继置为null
3.将头结点和尾结点置为空。

点击移步博客主页,欢迎光临~

偷cyk的图

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

将两个有序顺序表合并为一个新的有序顺序表,并由函数返回结果顺序表

将两个有序顺序表合并为一个新的有序顺序表&#xff0c;并由函数返回结果顺序表 算法思路&#xff1a; 这个其实就是一个归并排序&#xff0c;我们这里两顺序表为升序&#xff0c;要合并成一个升序表 用i和j分别标记顺序表A和顺序表B的元素&#xff0c;然后新表是C 每次从A和…

HarmonyOS 自定义抽奖转盘开发(ArkTS)

介绍 本篇 Codelab 是基于画布组件、显式动画&#xff0c;实现的一个自定义抽奖圆形转盘。包含如下功能&#xff1a; 1. 通过画布组件 Canvas&#xff0c;画出抽奖圆形转盘。 2. 通过显式动画启动抽奖功能。 3. 通过自定义弹窗弹出抽中的奖品。 相关概念 ● Stack组件…

web自动化测试框架介绍

一、目的 web自动化测试作为软件自动化测试领域中绕不过去的一个“香饽饽”&#xff0c;通常都会作为广大测试从业者的首选学习对象&#xff0c;相较于C/S架构的自动化来说&#xff0c;B/S有着其无法忽视的诸多优势&#xff0c;从行业发展趋、研发模式特点、测试工具支持&…

PMP考试是如何提高项目管理能力的?

通过获得PMP认证&#xff0c;项目管理人员可以提高其项目管理能力&#xff0c;并在行业中取得更高的职业发展。PMP如何提高项目管理能力&#xff0c;具体体现在以下几个方面&#xff1a; 1. 标准化方法&#xff1a; PMP认证基于《项目管理知识体系指南》(PMBOK)&#xff0c;该…

如何设计实时聊天系统的架构

1. 系统的要求和目标 1.1 功能要求 对话&#xff1a;系统应支持用户之间的一对一和群组对话。确认消息&#xff1a;系统应支持消息传递确认&#xff0c;如已发送、已送达、已读。共享&#xff1a;系统应支持媒体文件的共享&#xff0c;例如图像、视频和音频。聊天存储&#x…

IT行业哪个方向比较好就业?

IT行业哪个方向比较好就业? IT行业哪个方向比较好就业?引言IT技术发展背景及历程IT行业的就业方向有哪些&#xff1f;1. 软件开发2. 网络安全3. 数据分析4. 人工智能和机器学习5. 云计算6. 物联网&#xff08;IoT&#xff09;7. 软件测试与质量保障8. 区块链 分享在IT行业的就…

mac系统u盘启动盘制作教程,更新至macOS Sonoma 14

mac系统怎么制作装系统的u盘,如果您要在多台电脑上安装 macOS&#xff0c;而又不想每次都下载安装器&#xff0c;这时可引导安装器就会很有用。一起来看苹果电脑u盘启动盘制作教程吧。 Macos系统安装包合集包揽macos 10.15&#xff0c;macos 11和苹果最新系统等多个版本 1、A…

tomcat的负载均衡、动静分离(nginx联动)

动静分离&#xff1a; 访问静态页面和动态页面分开 实现动态和静态页面负载均衡 实验5台虚拟机 一、动态负载均衡 3台虚拟机模拟&#xff1a; 代理服务器&#xff1a;30 tomcat动态页面&#xff1a;21、22 代理服务器&#xff1a; proxy_pass http://tomcat; proxy_set_h…

【JavaEE】网络编程---UDP数据报套接字编程

一、UDP数据报套接字编程 1.1 DatagramSocket API DatagramSocket 是UDP Socket&#xff0c;用于发送和接收UDP数据报。 DatagramSocket 构造方法&#xff1a; DatagramSocket 方法&#xff1a; 1.2 DatagramPacket API DatagramPacket是UDP Socket发送和接收的数据报。…

调试-Debug

0.1 Debug环境介绍 Microsoft Visual Studio 2022中&#xff1a; Debug版本的可执行程序称为调试版本&#xff0c;包含调试信息&#xff0c;不作任何优化&#xff0c;便于程序员进行调试。 Release版本的可执行程序称为发布版本&#xff0c;进行了各种优化&#xff0c;不可调…

分类预测 | MATLAB实现SSA-CNN-BiLSTM-Attention数据分类预测(SE注意力机制)

分类预测 | MATLAB实现SSA-CNN-BiLSTM-Attention数据分类预测&#xff08;SE注意力机制&#xff09; 目录 分类预测 | MATLAB实现SSA-CNN-BiLSTM-Attention数据分类预测&#xff08;SE注意力机制&#xff09;分类效果基本描述模型描述程序设计参考资料 分类效果 基本描述 1.MAT…

金融行业网络安全保护与三级等保合规实施方案

金融行业网络安全保护与三级等保合规实施方案旨在帮助金融机构实施符合三级等保标准的网络安全保护措施。以下是一个基本的实施方案概述&#xff1a; 评估和规划&#xff1a; 进行风险评估&#xff1a;评估网络系统的风险&#xff0c;确定安全威胁、弱点和潜在风险。 确定等级…

嵌入式软件错误的五个主要原因

嵌入式学习路线领取在软件中查找和消除潜在的错误是一项艰巨的任务。通常需要英勇的努力和昂贵的工具才能从观察到的崩溃&#xff0c;死机或其他计划外的运行时行为追溯到根本原因。在最坏的情况下&#xff0c;根本原因会破坏代码或数据&#xff0c;使系统看起来仍然可以正常工…

JVM(一)

一、初始JVM 1.1 初始JVM JVM 本质上是一个运行在计算机上的程序,他的职责是运行Java字节码文件。 机器码是由二进制编码表示的计算机指令。每个机器码通常对应一个特定的操作,如加法、乘法、跳转等。机器码是计算机能够直接执行的代码,它可以在计算机的内存中存储和执行。…

VSCode 开发 Vue 语法提示

一. 打开应用商店&#xff0c;搜索 vetur &#xff0c;选择第一个&#xff0c;点击安装。 二. 安装完成后&#xff0c;还可以下载 Vue Language Features 解决代码警告的问题。 最后重启 VSCode 就可以使用啦。另外输入 按回车键还可以自动生成 vue 代码格式哦。 原创作者&…

2023年中国高尔夫球杆市场供需现状及趋势,量身定制会逐渐成为一种趋势[图]

随着高尔夫运动的发展&#xff0c;高尔夫球杆也在不断更新。20世纪80年代是高尔夫球杆设计与发展的黄金时期&#xff0c;大部分经典的球杆都是从这个时期被设计发明出来。高尔夫球杆的技术革新主要集中在杆头上&#xff0c;通过杆头的变化来提高和改善击球的效果。对应不同击球…

ATGM336H-5N一款高性能BDS/GNSS全星座定位导航模块

功能 概述 ATGM336H-5N系列模块是9.7X10.1尺寸的高性能BDS/GNSS全星座定位导航模块系列的总称。该系列模块产品都是基于中科微第四代低功耗GNSS SOC单芯片- -AT6558&#xff0c; 支持多种卫星导航系统&#xff0c;包括中国的BDS (北斗卫星导航系统)&#xff0c;美国的GPS,俄罗斯…

【Andriod】使用adb命令安装和卸载apk的通用python脚本

文章目录 1.前言2.连接设备3.从本机通过adb安装apk4.从本机通过adb卸载apk 1.前言 如不会使用adb请看之前的文章 【Andriod】adb调试安卓手机时连接真机或模拟器的3种方法&#xff0c;你知道么&#xff1f; 2.连接设备 import os # python标准库中的os模块""&qu…

更加轻松处理相同文件名!覆盖复制操作全新升级,避免重复命名!

亲爱的用户&#xff0c;您是否在进行覆盖复制操作时&#xff0c;常常因为相同的文件名而无法正常完成任务&#xff1f;现在&#xff0c;我们为您推出了全新的覆盖复制升级版&#xff0c;让您更加轻松处理相同文件名&#xff0c;避免重复命名的尴尬局面&#xff01; 首先第一步…

【23真题】四电四邮、专业课最简单的!

先科普下四电四邮有哪些&#xff1a;北邮、南邮、西邮、重邮、西电、成电、桂电、杭电 其中北邮、重邮、西电、成电&#xff0c;难度必须在第一梯队&#xff0c;毕竟大浪淘金&#xff0c;没点难度&#xff0c;没法筛人。南邮考通信原理&#xff0c;这里不做横向比较。桂电考信…