【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;//🙀
    }
}
相关推荐
有梦想的攻城狮1 小时前
maven中的maven-antrun-plugin插件详解
java·maven·插件·antrun
多吃蔬菜!!!2 小时前
排序算法C语言实现
数据结构
零叹2 小时前
篇章六 数据结构——链表(二)
数据结构·链表·linkedlist
硅的褶皱5 小时前
对比分析LinkedBlockingQueue和SynchronousQueue
java·并发编程
MoFe15 小时前
【.net core】天地图坐标转换为高德地图坐标(WGS84 坐标转 GCJ02 坐标)
java·前端·.netcore
季鸢5 小时前
Java设计模式之观察者模式详解
java·观察者模式·设计模式
Fanxt_Ja5 小时前
【JVM】三色标记法原理
java·开发语言·jvm·算法
Mr Aokey6 小时前
Spring MVC参数绑定终极手册:单&多参/对象/集合/JSON/文件上传精讲
java·后端·spring
-qOVOp-6 小时前
408第一季 - 408内容概述
数据结构
小马爱记录7 小时前
sentinel规则持久化
java·spring cloud·sentinel