【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 分钟前
数据结构:单向链表,顺序栈和链式栈
数据结构·链表
A懿轩A3 分钟前
【Maven 构建工具】从零到上手 Maven:安装配置 + IDEA 集成 + 第一个项目(保姆级教程)
java·maven·intellij-idea
野犬寒鸦12 分钟前
从零起步学习并发编程 || 第一章:初步认识进程与线程
java·服务器·后端·学习
我爱娃哈哈16 分钟前
SpringBoot + Flowable + 自定义节点:可视化工作流引擎,支持请假、报销、审批全场景
java·spring boot·后端
XiaoFan01235 分钟前
将有向工作流图转为结构树的实现
java·数据结构·决策树
睡一觉就好了。1 小时前
快速排序——霍尔排序,前后指针排序,非递归排序
数据结构·算法·排序算法
齐落山大勇1 小时前
数据结构——单链表
数据结构
小突突突1 小时前
浅谈Java中的反射
java·开发语言
Anastasiozzzz1 小时前
LeetCode Hot100 295. 数据流的中位数 MedianFinder
java·服务器·前端
我真的是大笨蛋1 小时前
Redo Log详解
java·数据库·sql·mysql·性能优化