算法 数据结构 双向环形链表 手撸环形链表 环形链表实现容器 环形链表添加修改删除获取大小 环形链表实现自定义容器 手撸容器 双向环形哨兵链表 数据结构(六)

 1. 环形链表:

                 

2. 建议先不要看我写得自己先实现下,只将Node内部类复制自己命名得容器内,

    实现方法:

                     a. add方法(添加到头部,尾部添加,指定位置添加)

                     b. get方法(获取首部,获取尾部,获取指定位置)

                     c. remove方法(删除首部,删除尾部,删除指定位置)

                     d. size方法(手动维护一个size变量,实现0(1)复杂度 )

                     e. 迭代器(实现迭代器,能够循环遍历)

     手动实现之后(每个功能只实现一种也可以),再回头参照,思考下即可!  

package com.nami.algorithm.study.day05;

import java.io.Serializable;
import java.util.Iterator;
import java.util.function.Consumer;

/**
 * 环形双向哨兵链表
 * 非线程安全
 * beyond u self and trust u self.
 *
 * @Author: lbc
 * @Date: 2023-09-01 9:07
 * @email: [email protected]
 * @Description: keep coding
 */
public class RingLinkedList<E> implements Serializable, Iterable<E>, Cloneable {

    /**
     * 容器已添加的元素
     */
    private int size = 1;

    /**
     * 哨兵节点
     */
    private Node sentinel = new Node(null, "-1", null);

    /**
     * 初始化哨兵
     */
    public RingLinkedList() {
        this.sentinel.prev = this.sentinel;
        this.sentinel.next = this.sentinel;
    }

    /**
     * 向链表添加数据
     *
     * @param element 添加的元素
     */
    public void addFirst(E element) {
        Node first = this.sentinel;
        Node next = first.next;
        Node node = new Node<>(first, element, next);
        first.next = node;
        next.prev = node;
        ++this.size;
    }

    /**
     * 向链表尾部添加数据
     *
     * @param element
     */
    public void addLast(E element) {
        Node last = this.sentinel.prev;
        Node node = new Node<>(last, element, sentinel);
        last.next = node;
        sentinel.prev = node;
        ++this.size;
    }
    
    /**
     * 获取容器指定位置的值
     *
     * @param index
     * @return
     */
    public E get(int index) {
        if (index > size - 1) {
            throw new IndexOutOfBoundsException("元素不存在");
        }
        Node next = sentinel.next;

        for (int i = 0; i < index; next = next.next, i++) {
        }
        if (sentinel == next) {
            throw new IndexOutOfBoundsException(String.format("index [%d] 不合法%n", index));
        }
        return (E) next.value;
    }

    /**
     * 获取指定位置节点node
     *
     * @param index
     * @return
     */
    private Node getNode(int index) {
        Node next = sentinel.next;

        for (int i = 0; i < index; next = next.next, i++) {
        }

        return next;
    }

    /**
     * 向元素指定节点添加值
     *
     * @param index
     * @param e
     */
    public void add(int index, E e) {
        if (index > size - 1) {
            throw new IndexOutOfBoundsException("元素不存在");
        }
        Node node = getNode(index);

        Node prev = node.prev;

        Node node1 = new Node(prev, e, node);
        node.prev = node1;
        prev.next = node1;
        ++this.size;
    }

    /**
     * 移除容器内第一个元素
     */
    public void removeFirst() {
        Node node = getNode(0);
        if (sentinel == node) {
            throw new IndexOutOfBoundsException(String.format("index [%d] 不合法%n", 0));
        }
        Node prev = node.prev;
        Node next = node.next;
        prev.next = next;
        next.prev = prev;
        --this.size;
    }

    /**
     * 删除第一个元素
     */
    public void removeFirst0() {
        Node removed = this.sentinel.next;

        if (removed == this.sentinel) {
            throw new IndexOutOfBoundsException("容器内已无元素");
        }
        Node next = removed.next;

        this.sentinel.next = next;
        next.prev = this.sentinel;
    }

    /**
     * 移除容器内指定位置元素
     *
     * @param index
     */
    public void remove(int index) {
        if (index > size - 1) {
            throw new IndexOutOfBoundsException(String.format("index [%d] 不合法%n", index));
        }

        Node node = getNode(index);

        if (sentinel == node) {
            throw new IndexOutOfBoundsException(String.format("index [%d] 不合法%n", 0));
        }

        Node prev = node.prev;

        Node next = node.next;

        prev.next = next;
        next.prev = prev;
        --this.size;
    }

    /**
     * 删除最后一个节点
     */
    public void removeLast() {
        Node prev = this.sentinel.prev;
        if (prev == this.sentinel) {
            return;
        }

        Node next = prev.next;
        Node prev0 = prev.prev;
        prev0.next = next;
        next.prev = prev0;
        --this.size;
    }

    /**
     * 获取容器大小
     *
     * @return
     */
    public int size() {
        return this.size - 1;
    }

    /**
     * 迭代器遍历
     *
     * @return
     */
    @Override
    public Iterator iterator() {
        return new NodeIterator();
    }

    /**
     * 匿名内部类
     * 内部类使用到了外部类的成员变量时,不能使用static修饰
     */
    private class NodeIterator implements Iterator {
        Node node = sentinel.next;

        @Override
        public boolean hasNext() {
            return node != sentinel;
        }

        @Override
        public Object next() {
            Object value = node.value;
            node = node.next;
            return value;
        }
    }

    /**
     * while实现
     *
     * @param consumer
     */
    public void forEach(Consumer consumer) {
        Node firstNode = this.sentinel.next;
        while (firstNode != sentinel) {
            consumer.accept(firstNode.value);
            firstNode = firstNode.next;
        }
    }

    /**
     * Node类型 节点对象
     * 二者为组合关系,所以 由外部类变为内部类,对外隐藏实现细节
     */
    private static class Node<E> {

        /**
         * 上一个节点
         */
        private Node<E> prev;

        /**
         * 值
         */
        private E value;

        /**
         * 下一个节点
         */
        private Node<E> next;


        public Node(Node<E> prev, E value, Node<E> next) {
            this.prev = prev;
            this.value = value;
            this.next = next;
        }

    }

}

猜你喜欢

转载自blog.csdn.net/qq_33919114/article/details/132670186
今日推荐