LinkedList模拟实现

1.链表的头插

2.链表的尾插

3.在链表中任意位置前插入

4.查找链表中是否有某一个值val

5.删除第一次出现的值key

6.删除所有出现的值key

在实现链表的功能前,我们首先要明白链表是由每一个结点构成的,每一个结点其实就是一个类,是由val值域和next域构成的,所以我们要先构造一个结点类,即静态内部类

java 复制代码
public LinkedList {
        //创建结点
    static class ListNode{
        //每个结点都有val值域和next结点域组成
        public int val;
        public ListNode next;

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

让后我们手动创建一个链表,然后让每一个结点next指向下一个结点的

1.链表的头插

在进行头插的时候,我们需要判断这个链表是否为空,如果链表为空的话,那么链表的head就是要插入的新结点,这个需要我们注意

java 复制代码
    public void addFirst(int val) {
        //申请新的结点
        ListNode newNode = new ListNode(val);

        //判断链表是否为空,如果链表为空,那么要插入的结点就是head
        if(head == null) {
            head = newNode;
            return;
        }

        //否则就进行头插
        newNode.next = head;
        head = newNode;
    }

2.链表的尾插

链表的尾插,只需要判断这个链表是否为空,如果为空,那么就相当于头插,如果不为空,那么就只需要我们找到链表的最后一个结点即可

java 复制代码
    public void addLast(int val) {
        ListNode newNode = new ListNode(val);
        if(head == null) {
            head = newNode;
            return;
        }

        //如果链表不为空,那么就要找到最后一个结点
        //定义cur去查找最后一个结点,不要用head去找,不然找完后head就不指向第一个结点了
        ListNode cur = head;
        while(cur.next != null) {
            cur = cur.next;
        }

        cur.next = newNode;
    }

3.在链表中任意位置前插入

在任意位置插入的时候,如果插入的位置为0或者为size,那么就是头插或者尾插,插入前要判断插入的位置是否合法,如果插入的位置<0或者>size,那么插入失败,否则就要找到插入的结点的前一个结点

java 复制代码
 public void addIndext(int pos, int val) {
        ListNode newNode = new ListNode(val);
        if(pos < 0 || pos > size()) {
            System.out.println("插入位置非法!!!,程序退出");
            return;
        }

        if(pos == 0) {
            //头插
            addFirst(val);
            return;
        } else if(pos == size()) {
            //尾插
            addLast(val);
            return;
        }

        //找到要插入的结点的前一个结点
        ListNode cur = head;
        for(int i = 1; i < pos; i++) {
            cur = cur.next;
        }

        //出了循环,cur就在要插入的结点的前面
        newNode.next = cur.next;
        cur.next = newNode;
    }

4.查找链表中是否有某一个值val

java 复制代码
    public boolean contains(int key) {
        ListNode cur = head;
        while(cur != null) {
            if(cur.val == key) {
                System.out.println("查找成功");
                return true;
            }

            cur = cur.next;
        }
        System.out.println("查找失败");
        return false;
    }

5.删除第一次出现的值key

首先先判断链表是否为空,如果不为空,则先判断头结点是不是就是val,如果是,那么让头结点向后走即可,如果不是,那么遍历一次链表看是否能找到,如果找不到则说明这个链表没有这个val值

java 复制代码
    public void remove(int key) {

        ListNode cur = head;
        //判断链表是否为空
        if(head == null) {
            System.out.println("链表为空,无此关键字");
            return;
        }

        if(cur.val == key) {
            head = head.next;
            return;
        }

        while(cur.next != null) {
            if(cur.next.val == key) {
                cur.next = cur.next.next;
                System.out.println("删除成功");
                return;
            }
            cur = cur.next;
        }

        System.out.println("此链表无此关键字key->" + key);

    }

6.删除所有出现的值key

java 复制代码
public void removeAllKey(int key) {

        ListNode cur = head.next;
        ListNode prev = head;
        if(cur == null) {
            System.out.println("链表为空,程序退出");
            return;
        }

        while(cur != null) {
            if(cur.val == key) {
                prev.next = cur.next;
                cur = cur.next;
            }else {
                prev = prev.next;
                cur = cur.next;
            }
        }

        //最后判断一下头结点是否为val值
        if(head.val == key) {
            head = head.next;
        }
    }

总结:

在创建链表的时候,我们要清楚链表是由一个个结点构成的,而每一个结点都是由val域和next域构成,所以我们可以将结点看成一个类,然后在模拟实现方法的时候,我们都要先判断这个链表是否为空,而顺序表是判断是否为满。

相关推荐
机器人零零壹1 小时前
技术白皮书:iRobotCAM如何解决机器人激光切割应用中的核心难点,从CAD离线编程到双目视觉定位与轨迹自适应提升复杂空间曲线切割的精度、效率与柔性化水平
人工智能·算法
AI你一生一世3 小时前
不止于时序存储:DolphinDB 如何成为 AI 时代的工业智能底座
java·人工智能·struts·时序数据库·工业智能·dolphindb·ai基础设施
布莱克6053 小时前
C/C++ 中变量的声明与定义:区别、联系与常见误区
c语言·开发语言·c++·声明·定义
云-缩影3 小时前
拆解 AI 图像生成应用的后端架构:ECS、OSS 和大模型 API 怎么配合
java·spring boot·后端
LabVIEW开发3 小时前
LabVIEW 局部变量为何引发竞争条件?四种同步机制
开发语言·labview
瑞克-桑切斯3 小时前
7、MySQL 慢查询排查与优化实战指南
java·服务器·数据库
benchmark_cc4 小时前
A 股、港股、美股如何建立统一的标的主数据格式?
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
ZhengEnCi4 小时前
大模型的分类到底怎么分:从基础模型到推理模型、从通用到专用的完整图谱
算法
前进的李工5 小时前
Agent 学习笔记 05:系统提示词应该怎么写
笔记·学习·prompt·agent·个人开发·few-shot·ai应用开发
Zenova EdgeOS5 小时前
Go 工业边缘错误处理实战:用 errors 构建可追溯错误链
开发语言·数据库·golang