package mydata;

import java.util.Iterator;

/**
 *  自定义链表,实现链表的基本功能
 */
public class MyLinkedList<E> implements Iterable<E> {

    /**
     *  节点类,表示链表中的一个节点
     */
    private static class Node<E>{

        /* 节点的值 */
        public E data;

        /* 前一个节点 */
        public Node<E> prev;

        /* 后一个节点 */
        public Node<E> next;

        /* 节点构造器 */
        public Node(E data, Node<E> prev, Node<E> next){
            this.data = data;
            this.prev = prev;
            this.next = next;
        }
    }

    /* 链表大小 */
    private int theSize;

    /* 链表修改次数 */
    private int modCount = 0;

    /* 链表起点标记节点 */
    private Node<E> beginMarker;

    /* 链表末尾标记节点 */
    private Node<E> endMarker;

    /*
     * 链表构造器
     */
    public MyLinkedList(){
        doClear();
    }

    /*
     * 清除链表
     * @return: void
     */
    public void clear(){
        doClear();
    }

    /*
     * 执行清除,初始化链表
     * @return: void
     */
    private void doClear(){
        beginMarker = new Node<>(null, null, null);
        endMarker = new Node<>(null, beginMarker, null);
        beginMarker.next = endMarker;
        theSize = 0;
        modCount++;
    }

    /*
     * 返回链表大小
     * @return: int
     */
    public int size(){
        return theSize;
    }

    /*
     * 链表是否为空
     * @return: boolean
     */
    public boolean isEmpty(){
        return size() == 0;
    }

    /*
     * 在链表末尾插入
     * @param val : 要插入的值
     * @return: boolean
     */
    public boolean add(E val){
        add(size(), val);
        return true;
    }

    /*
     * 在指定位置插入值
     * @param index : 指定索引
     * @param val : 要插入的值
     * @return: void
     */
    public void add( int index, E val){
        if(index  > size()){
            throw new IllegalStateException();
        }
        if(isEmpty()){
            Node<E> p = new Node<>(val, beginMarker, endMarker);
            beginMarker.next = p;
            endMarker.prev = p;
            modCount++;
            theSize++;
        }else {
            if(index == size()){
                Node<E> p = new Node<>(val, endMarker.prev, endMarker);
                p.prev.next = p;
                endMarker.prev = p;
                modCount++;
                theSize++;
            }else {
                addBefore(getNode(index, 0, size() - 1), val);
            }
        }
    }

    /*
     * 获取指定索引的值
     * @param index : 指定索引
     * @return: E
     */
    public E get(int index){
        return getNode(index).data;
    }

    /*
     * 设置指定索引的值
     * @param index : 索引
     * @param newVal : 新值
     * @return: E
     */
    public E set(int index, E newVal){
        Node<E> old = getNode(index);
        E oldData = old.data;
        old.data = newVal;
        return oldData;
    }

    /*
     * 删除指定索引的节点
     * @param index : 索引
     * @return: E:所删除节点的值
     */
    public E remove(int index){
        return remove(getNode(index));
    }

    /*
     * 在节点之前添加新节点
     * @param p : 新节点的下一位
     * @param val : 新节点的值
     * @return: void
     */
    private void addBefore(Node<E> p, E val){
        Node<E> newNode = new Node<>(val, p.prev, p);
        newNode.prev.next = newNode;
        p.prev = newNode;
        theSize++;
        modCount++;
    }

    /*
     * 移除节点
     * @param p : 被移除的节点
     * @return: E:被移除节点的值
     */
    private E remove(Node<E> p){
        p.prev.next = p.next;
        p.next.prev = p.prev;
        theSize--;
        modCount++;
        return p.data;
    }

    /*
     * 根据索引获取节点
     * @param index : 索引
     * @return: mydata.MyLinkedList.Node<E>
     */
    private Node<E> getNode(int index){
        return getNode(index, 0, size()-1);
    }

    /*
     * 根据索引和上下界获取节点
     * @param index : 索引
     * @param lower : 索引下界
     * @param upper : 索引上界
     * @return: mydata.MyLinkedList.Node<E>
     */
    private Node<E> getNode(int index, int lower, int upper){
        if(isEmpty()){
            return null;
        }
        Node<E> p;
        if(index < lower || index > upper){
            throw new IndexOutOfBoundsException();
        }
        if(index < size()/2){
            p = beginMarker.next;
            for(int i = 0; i < index; i++ ){
                p = p.next;
            }
        }else{
            p = endMarker.prev;
            for( int i = size()-1; i > index; i--){
                p = p.prev;
            }
        }
        return p;
    }

    /*
     * 获取迭代器
     * @return: java.util.Iterator<E>
     */
    public Iterator<E> iterator(){
        return new LinkedListIterator();
    }

    /**
     *自定义迭代器
     */
    private class LinkedListIterator implements Iterator<E>{

        /* 目前节点 */
        private Node<E> current = beginMarker.next;

        /* 期望的修改次数 */
        private int expectedModCount = modCount;

        /* 是否可以删除标志 */
        private boolean okToRemove = false;

        /*
         * 是否还有下一个节点
         * @return: boolean
         */
        public boolean hasNext(){
            return current != endMarker;
        }

        /*
         * 获取当前节点的值,并指向下一个节点
         * @return: E
         */
        public E next(){
            if(modCount != expectedModCount){
                throw new java.util.ConcurrentModificationException();
            }
            if(!hasNext()){
                throw new java.util.NoSuchElementException();
            }
            current = current.next;
            okToRemove = true;
            return  current.prev.data;
        }

        /*
         * 删除上一节点
         * @return: void
         */
        public void remove(){
            if(modCount != expectedModCount){
                throw new java.util.ConcurrentModificationException();
            }
            if(!okToRemove){
                throw new IllegalStateException();
            }
            MyLinkedList.this.remove(current.prev);
            expectedModCount++;
            okToRemove = false;
        }
    }
}

 

posted on 2019-05-27 11:04  Lotz  阅读(278)  评论(0)    收藏  举报