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域构成,所以我们可以将结点看成一个类,然后在模拟实现方法的时候,我们都要先判断这个链表是否为空,而顺序表是判断是否为满。

相关推荐
雨中飘荡的记忆32 分钟前
大流量下库存扣减的数据库瓶颈:Redis分片缓存解决方案
java·redis·后端
心之语歌3 小时前
基于注解+拦截器的API动态路由实现方案
java·后端
华仔啊4 小时前
Stream 代码越写越难看?JDFrame 让 Java 逻辑回归优雅
java·后端
ray_liang4 小时前
用六边形架构与整洁架构对比是伪命题?
java·架构
AI软著研究员4 小时前
程序员必看:软著不是“面子工程”,是代码的“法律保险”
算法
FunnySaltyFish5 小时前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
Ray Liang6 小时前
用六边形架构与整洁架构对比是伪命题?
java·python·c#·架构设计
颜酱6 小时前
理解二叉树最近公共祖先(LCA):从基础到变种解析
javascript·后端·算法
Java水解6 小时前
Java 中间件:Dubbo 服务降级(Mock 机制)
java·后端
SimonKing10 小时前
OpenCode AI辅助编程,不一样的编程思路,不写一行代码
java·后端·程序员