【Java】/* 双向链表 - 底层实现 */

【难点】:remove、removeAllKey

一、IList

java 复制代码
package bagfive;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: tangyuxiu
 * Date: 2024-08-21
 * Time: 20:30
 */
public interface IList<E> {
    //头插法
    void addFirst(E data);
    //尾插法
    void addLast(E data);
    //任意位置插入,第一个数据节点为0号下标
    void addIndex(int pos,E data);
    //查找是否包含关键字key是否在单链表当中
    boolean contains(E key);
    //删除第一次出现关键字为key的节点
    void remove(E key);
    //删除所有值为key的节点
    void removeAllKey(E key);
    //得到单链表的长度
    int size();
    void display();
    void clear();
}

二、MyLinkedList

java 复制代码
package bagfive;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: tangyuxiu
 * Date: 2024-08-21
 * Time: 20:30
 */
public class MyLinkedList<E> implements IList<E> {

    /* 使用内部类定义双向链表节点 */
    private static class ListNode<E> {
        E val;
        ListNode<E> prev;
        ListNode<E> next;

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

    private ListNode<E> head;
    private ListNode<E> last;

    @Override
    public void addFirst(E data) {
        ListNode<E> newNode = new ListNode<>(data);
        //1. 如果链表为null
        if (this.head == null) {
            this.head = this.last = newNode;
            return;
        }
        //2. 链表不为null
        newNode.next = this.head;
        this.head.prev = newNode;
        this.head = newNode;
    }

    @Override
    public void addLast(E data) {
        ListNode<E> newNode = new ListNode<>(data);
        //1. 如果链表为null
        if (this.head == null) {
            this.head = this.last = newNode;
            return;
        }
        //2. 链表不为null
        this.last.next = newNode;
        newNode.prev = this.last;
        this.last = newNode;
    }

    /* 判断add的位置是否合法 */
    private boolean addIndexIsLegal(int pos) {
        if (pos < 0 || pos > this.size()) {
            return false;
        }
        return true;
    }

    @Override
    public void addIndex(int pos, E data) {
        //1. 判断pos位置是否合法
        if (!this.addIndexIsLegal(pos)) {
            return;
        }
        //2. pos == 0
        if (pos == 0) {
            this.addFirst(data);
            return;
        }
        //3. pos == size()
        if (pos == this.size()) {
            this.addLast(data);
            return;
        }
        //4. 其他位置,不需要找前驱节点了
        ListNode<E> newNode = new ListNode<>(data);
        ListNode<E> cur = this.head;
        for (int i = 0; i < pos; i++) {
            cur = cur.next;
        }
        newNode.next = cur;
        cur.prev.next = newNode;
        newNode.prev = cur.prev;
        cur.prev = newNode;
    }

    @Override
    public boolean contains(E key) {
        ListNode<E> cur = this.head;
        while (cur != null) {
            if (cur.val.equals(key)) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

    @Override
    public void remove(E key) {
        // 头,任意,尾 (链表为null进不去循环)
        ListNode<E> del = this.head;
        while (del != null) {
            if (del.val.equals(key)) {
                if (this.head == del) {//如果为头节点
                    if (this.head.next == null) {//如果为头节点,且链表只有一个节点
                        this.head = this.last = null;
                    } else {
                        this.head = this.head.next;
                        this.head.prev = null;
                    }
                } else {
                    if (this.last == del) {//如果为尾节点
                        this.last = this.last.prev;
                        this.last.next = null;
                    } else {//其他位置
                        del.prev.next = del.next;
                        del.next.prev = del.prev;
                    }
                }
                return;
            }
            del = del.next;
        }
    }

    @Override
    public void removeAllKey(E key) {
        // 头,只一个节点,任意,尾 (链表为null进不去循环)
        ListNode<E> del = this.head;
        while (del != null) {
            if (del.val.equals(key)) {
                if (this.head == del) {//如果为头节点
                    if (this.head.next == null) {//如果为头节点,且链表只有一个节点
                        this.head = this.last = null;
                    } else {
                        this.head = this.head.next;
                        this.head.prev = null;
                    }
                } else {
                    if (this.last == del) {//如果为尾节点
                        this.last = this.last.prev;
                        this.last.next = null;
                    } else {
                        del.prev.next = del.next;//其他位置
                        del.next.prev = del.prev;
                    }
                }
            }
            del = del.next;
        }
    }

    @Override
    public int size() {
        int count = 0;
        ListNode<E> cur = this.head;
        while (cur != null) {
            count++;
            cur = cur.next;
        }
        return count;
    }

    @Override
    public void display() {
        ListNode<E> cur = this.head;
        while (cur != null) {
            System.out.print(cur.val + " ");
            cur = cur.next;
        }
        System.out.println();
    }

    @Override
    public void clear() {
        ListNode<E> cur = this.head;
        while (cur != null) {
            cur.val = null;
            cur = cur.next;
        }
        this.head = this.last = null;//🙀
    }
}
相关推荐
苹果醋316 分钟前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
Hello.Reader35 分钟前
深入解析 Apache APISIX
java·apache
菠萝蚊鸭1 小时前
Dhatim FastExcel 读写 Excel 文件
java·excel·fastexcel
旭东怪1 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
007php0071 小时前
Go语言zero项目部署后启动失败问题分析与解决
java·服务器·网络·python·golang·php·ai编程
∝请叫*我简单先生1 小时前
java如何使用poi-tl在word模板里渲染多张图片
java·后端·poi-tl
ssr——ssss1 小时前
SSM-期末项目 - 基于SSM的宠物信息管理系统
java·ssm
一棵星2 小时前
Java模拟Mqtt客户端连接Mqtt Broker
java·开发语言
鲤籽鲲2 小时前
C# Random 随机数 全面解析
android·java·c#
zquwei2 小时前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring