数据结构之单链表的模拟实现

news2025/3/15 11:36:40

  💕"你笑的次数越多越好,因为你只有用笑才能不怀恶意地消灭罪恶。"💕

作者:Mylvzi 

 文章主要内容:数据结构之单链表的模拟实现 

 

MyArrayList

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 绿字
 * Date: 2023-10-16
 * Time: 19:37
 */
public class MySingleList {

    // 定义为内部类
    static class ListNode {
        public int data;// 数据域
        public ListNode next;// 指针域  默认是null

        public ListNode(int data) {
            this.data = data;
        }
    }

    // 对于整个链表来说,只需一个head即可
    public ListNode head;

    // 创建一个单链表(穷举法)
    public void createList() {
        ListNode node1 = new ListNode(12);
        ListNode node2 = new ListNode(23);
        ListNode node3 = new ListNode(34);
        ListNode node4 = new ListNode(45);
        ListNode node5 = new ListNode(56);

        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node5;

        this.head = node1;
    }

    // 打印链表
    public void display() {
        // 保持head 不动  重新赋值给cur
        ListNode cur = head;
        while (cur != null) {
            System.out.print(cur.data+ " ");
            cur = cur.next;
        }

        System.out.println();
    }

    /**
     * 从指定位置打印
     */
    public void display(ListNode newHead) {
        // 保持head 不动  重新赋值给cur
        ListNode cur = newHead;
        while (cur != null) {
            System.out.print(cur.data+ " ");
            cur = cur.next;
        }

        System.out.println();
    }

    // 返回链表长度
    public int size() {
        int cnt = 0;
        ListNode cur = head;
        while (cur != null) {
            cnt++;
            cur = cur.next;
        }

        return cnt;
    }

    // 判断是否包含数据域为key的结点
    public boolean contains(int key) {
        ListNode cur = head;
        while (cur != null) {
            if(cur.data == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }


    // 头插
    public void addFirst(int data) {
        ListNode newhead = new ListNode(data);

        newhead.next = head;
        head = newhead;
    }

    // 尾插
    public void addTail(int data) {
        ListNode newtail = new ListNode(data);
        ListNode cur = head;

        // 注意如果链表为空的时候不能访问其next  要单独处理
        if (cur == null) {
            head = newtail;
            return;// 一定要return,去结束异常
        }

        while(cur.next != null) {
            cur = cur.next;
        }

        cur.next = newtail;
    }

    // 在Index位置插入
    public void addIndex(int index,int data){
        // 检查Index合法性
        if(index < 0 || index > size()) {
            throw new IndexOutOfBoundException("位置异常");
        }

        if(index == 0) {
            addFirst(data);
            return;
        }

        if(index == size()) {
            addTail(data);
            return;
        }

        // 让cur走到index的前驱结点
        ListNode newnode  = new ListNode(data);
        ListNode cur = findPrevOfIndex(index);

        newnode.next = cur.next;
        cur.next = newnode;
    }

    // 将找前驱结点包装成一个方法 找到index位置的前一个结点  让cur走index-1步
    private ListNode findPrevOfIndex(int index) {
        ListNode cur = head;

        while (index != 1) {
            cur = cur.next;
            index--;
        }

        return cur;
    }

    // 删除值为key的结点(第一次出现的)
    public void remove(int key) {
        if (head == null) {
            return;
        }

        // 单独删除头节点  因为其没有前驱节点 不是只有一个节点
        if (head.data == key) {
            head = head.next;
            return;
        }


        // 先找前驱节点
        ListNode cur = findPrevOfKey(key);
        if (cur == null) {
            System.out.println("未找到你要删除的结点");
            return;
        }
        cur.next = cur.next.next;

//        ListNode del = cur.next;
//        cur.next = del.next;
    }

    // 找到数据域为key的结点的前一个结点
    private ListNode findPrevOfKey(int key) {
        ListNode cur = head;

        while (cur.next != null) {
            if (cur.next.data == key) {
                return cur;
            }

            cur = cur.next;
        }

        // 未找到该节点
        return null;
    }

    //
    public void removeAll(int key) {
        if (head == null) {
            return;
        }
        ListNode prev = head;
        ListNode cur = head.next;

        while (cur != null) {
            if (head.data == key) {
                head = head.next;
                // 此处不需要return
            }

            // 等于key
            if(cur.data == key) {
                prev.next = cur.next;
                cur = prev.next;
                continue;// 一定要添加一个continue,否则会与下面的代码重复
            }

            prev = prev.next;
            cur = cur.next;
        }
    }

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

    public ListNode reverseList() {
        // 当链表为空时,或者只有一个节点(此时不需要反转了)直接返回即可
        if(head == null) return head;
        if(head.next == null) return head;

        ListNode cur = head.next;

        // 要给最初的head的next置空,否则会成环
        head.next = null;

        while(cur != null) {
            ListNode curNext = cur.next;

            cur.next = head;
            head = cur;

            cur = curNext;
        }

        return head;
    }




}

异常

public class IndexOutOfBoundException extends RuntimeException{
    public IndexOutOfBoundException(String message) {
        super(message);
    }
}

测试类:

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 绿字
 * Date: 2023-10-16
 * Time: 19:41
 */
public class SingleListTest {
    public static void main(String[] args) {
        MySingleList mySingleList = new MySingleList();
//        mySingleList.createList();
        mySingleList.addFirst(1);
        mySingleList.addFirst(2);
        mySingleList.addFirst(3);
        mySingleList.addFirst(4);
        mySingleList.addFirst(5);
        mySingleList.display();
        System.out.println("=============================");
        MySingleList.ListNode newHead = mySingleList.reverseList();
        mySingleList.display(newHead);


















/*        mySingleList.addTail(5);
        mySingleList.addTail(5);
        mySingleList.addTail(5);
        mySingleList.addTail(5);
        mySingleList.addTail(5);
        mySingleList.addTail(5);
        mySingleList.display();
        System.out.println();
//        mySingleList.removeAll(5);
        mySingleList.display();*/
//        mySingleList.addIndex(0,999);
//        mySingleList.remove(1);
//        mySingleList.remove(999);
//        mySingleList.addTail(999999);
//        mySingleList.display();
//        mySingleList.addTail(199);
//
//        mySingleList.addIndex(1,12);
//        mySingleList.addIndex(0,999999999);
//        mySingleList.addIndex(-1,12);

//        mySingleList.display();
/*        mySingleList.display();
        System.out.println(mySingleList.size());
        System.out.println(mySingleList.contains(12));
        System.out.println(mySingleList.contains(1));*/

    }
}

 

 

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

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

相关文章

F5.5G落进现实:目标网带来的光之路

数字化与智能化的世界将走向何方&#xff1f;这个问题有着非常复杂的答案&#xff0c;但其中有一个答案已经十分清晰。那就是智能化的下一步&#xff0c;必将走向泛在万兆的世界。 网络是算力联接的底座&#xff0c;是智能演化的基础。纵观每一代数字化升级&#xff0c;都可以发…

2023秋招华为技术岗线上面试经历

2023/10/16 个人情况&#xff1a;博士&#xff0c;预计2024年毕业&#xff0c;参加了2023秋招&#xff0c;华为应聘到3面主管面。 下面按招聘流程顺序&#xff0c;记录我的面试经历。因为想写详细一点的独立文章&#xff0c;所以想来想去还是放到CSDN上。 1. 宣讲会 宣讲会…

kr 第三阶段(一)16 位汇编

为什么要学习 16 位汇编&#xff1f; 16 位汇编包含了大部分 32 位汇编的知识点。有助于在学习内核的两种模式。 实模式&#xff1a;访问真实的物理内存保护模式&#xff1a;访问虚拟内存 有助于提升调试能力&#xff0c;调试命令与 OllyDbg 和 WinDebug 通用。可以学习实现反…

spring boot整合MongoDB 一

MongoDB介绍 应用场景 传统的关系型数据库&#xff08;如MySQL&#xff09;&#xff0c;在数据操作的“三高”需求以及应对Web2.0的网站需求面前&#xff0c;显得力不从心。 解释&#xff1a;“三高”需求&#xff1a; • High performance - 对数据库高并发读写的需求。 • …

制作.a静态库 (封盒)

//云库房间 1.GitHub上创建开源框架项目须包含文件&#xff1a; LICENSE:开源许可证&#xff1b;README.md:仓库说明文件&#xff1b;开源项目&#xff1b;(登录GitHub官网) 2. 云仓储库构建成功(此时云库中没有内容三方框架)&#xff01;&#xff01;&#xff01; 3. 4.5. //…

数仓建设(二)

1) 指标梳理 指标口径的不一致使得数据使用的成本极高&#xff0c;经常出现口径打架、反复核对数据的问题。在数据治理中&#xff0c;我们将需求梳理到的所有指标进行进一步梳理&#xff0c;明确其口径&#xff0c;如果存在两个指标名称相同&#xff0c;但口径不一致&#xff0…

项目管理之生命周期管理

项目生命周期管理矩阵是项目管理中一个重要的概念&#xff0c;它包括了项目从准备到收尾的各个阶段。项目生命周期管理矩阵以四个主要管理阶段为基础&#xff0c;分别为准备阶段、启动阶段、执行阶段和收尾阶段。这四个阶段在项目管理中有着明确的目标和职责&#xff0c;贯穿了…

【LeetCode】35. 搜索插入位置

1 问题 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出: 2 示例…

GPT4 Plugins 插件 WebPilot 生成抖音文案

1. 生成抖音文案 1.1. 准备1篇优秀的抖音文案范例 1.2. Promept公式 你是一个有1000万粉丝的抖音主播&#xff0c; 请模仿下面的抖音脚本文案&#xff0c;重新改与一篇文章改写成2分钟的抖音视频脚本&#xff0c; 要求前一部分是十分有争议性的内容&#xff0c;并且能够引发…

linux进程间通讯--信号量

1.认识信号量 方便理解&#xff1a;信号量就是一个计数器。当它大于0能用&#xff0c;小于等于0&#xff0c;用不了&#xff0c;这个值自己给。 2.特点&#xff1a; 信号量用于进程间同步&#xff0c;若要在进程间传递数据需要结合共享内存。信号量基于操作系统的 PV 操作&am…

GitHub仓库的README文件无法显示图片问题-非域名污染原因

之前上自己仓库就偶然发现图片不显示现象&#xff0c;当时以为是网络问题就没有留意这事。但是一直不显示就有问题了&#xff01;于是网上搜了一遭&#xff0c;看见大家遇到此现象的原因普遍归于DNS污染1而我的问题原来是MarkDown格式&#xff01; 在图片语法前不要加分区语法…

linux部署gitlab

1. 配置yum源&#xff1a; vim /etc/yum.repos.d/gitlab-ce.repo [gitlab-ce] nameGitlab CE Repository baseurlhttps://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el$releasever/ gpgcheck0 enabled1 2. 更新本地缓存 sudo yum install -y gitlab-ce 3. 安装相关依赖 yum …

RT-Thread学习笔记(三):线程管理

线程管理 线程管理相关概念什么是时间片轮转调度器锁线程运行机制线程的五种状态 动态和静态创建线程区别动态和静态创建线程优缺点RT-Thread动态线程管理函数动态创建线程动态删除线程 RT-Thread静态线程管理函数静态创建线程 线程其他操作线程启动线程延时获得当前执行的线程…

基于nodejs+vue小型企业银行账目管理系统

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

九阳真经之各大厂校招

大学计算机系的同学要怎么努力才能校招进大厂? 秋招的大公司非常多&#xff0c;也是非常好的&#xff0c;赶上了秋招&#xff0c;你基本工作就敲定了&#xff0c;在整个应届毕业生的人群中你就占据很大的优势了。 如何准备应届校招&#xff1f; 一、做好规划&#xff0c;把…

Python 网络爬虫

爬虫原理 计算机一次Request请求和服务器端的Response回应&#xff0c;即实现了网络连接。 爬虫需要做两件事&#xff1a;模拟计算机对服务器发起Request请求。 接受服务器的Response内容并解析、提取所需的信息。 多页面爬虫流程 ​​​​​​​多页面网页爬虫流程

Map中key和value值是否可以为null或空字符串?

Map中key和value值是否可以为null或空字符串? 答案&#xff1a; HashMap既支持分别为空/null&#xff0c;也支持key和value同时为空/nullHashtable不支持key和value存储null&#xff0c;但支持存空字符串** HashMap HashMap是中支持空键和空值的&#xff0c;不论存入null或…

python每日一练(9)

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

右值引用+移动语义

目录 右值引用 引入 介绍 左值 左值引用 左值引用的缺陷 引入 缺陷 解决 右值 纯右值 将亡值 右值引用 move函数 介绍 底层实现 参数 -- 通用引用类型 引用折叠 折叠规则: 返回值 remove_reference 移动 引入 介绍 移动构造函数 介绍 是否抛出异常…

SpringBoot+SpringSecurity项目的创建

首先创建一个springboot项目&#xff0c;注意springboot要求jdk版本在17以上 等项目构建完成之后&#xff0c;在pom文件中加入SpringSecurity的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-securi…