3、单链表、双链表、循环链表代码实现

122 阅读3分钟
单链表:链表结构不同于数组,它非内部连续的空间,他是通过指针进行相连
双链表:双链表不同于单链表的是他维护有两个指针,一个指向前一个元素,一个指向后一个元素
循环链表:他的特点是它为一个环形,及链表尾部的下一个指针域指向头部
  • 单链表代码实现
public class LitGrassSingleLinkedList<T> implements Iterable<T> {  
  
    //维护一个头指针  
    private Node<T> head;  
    //尾部指针  
    private Node<T> last;  
    private int size;  
    private int modCount = 0;  
  
  
    public LitGrassSingleLinkedList(){  
        head = new Node<>(null,null);  
        last = head;  
        size = 0;  
    }  
  
    public void clear(){  
        doClear();  
    }  
  
    public int size(){  
        return size;  
    }  
  
    private void linkLast(T e){  
        Node<T> p = last;  
        Node<T> newNode = new Node<>(e, null);  
        last = newNode;  
        p.next = newNode;  
        size++;  
        modCount++;  
    }  
  
    private void linkBefore(T e,Node<T> before,Node<T> next){  
        Node<T> newNode = new Node<>(e, next);  
        before.next = newNode;  
        size++;  
        modCount++;  
    }  
  
  
  
    public void add(T e){  
        linkLast(e);  
    }  
  
    public void add(T e,int index){  
        checkPositionIndex(index);  
  
        if (index == size)  
            linkLast(e);  
        else  
            linkBefore(e, node(index-1),node(index-1).next);  
  
    }  
  
    public T get(int index){  
        checkElementIndex(index);  
  
        return node(index).element;  
    }  
  
    public void set(T e,int index){  
        checkElementIndex(index);  
  
        node(index).element = e;  
    }  
  
    public T remove(int index){  
        checkElementIndex(index);  
  
        Node<T> pre = node(index-1);  
        Node<T> node  = pre.next;  
        Node<T> next = node.next;  
  
        pre.next = next;  
        if(next == null){  
            last = pre;  
        }  
        size--;  
        modCount++;  
        return node.element;  
    }  
  
    private Node<T> node(int index){  
        if(index == -1){  
            return head;  
        }  
        Node<T> x = head.next;  
        for (int i = 0; i < index; i++)  
            x = x.next;  
        return x;  
    }  
  
    private boolean isPositionIndex(int index){  
        return index >= 0 && index <= size;  
    }  
  
    private void checkPositionIndex(int index) {  
        if (!isPositionIndex(index))  
            throw new IndexOutOfBoundsException();  
    }  
  
    private void checkElementIndex(int index) {  
        if (!isElementIndex(index))  
            throw new IndexOutOfBoundsException();  
    }  
  
    private boolean isElementIndex(int index) {  
        return index >= 0 && index < size;  
    }  
  
    private void doClear(){  
        Node<T> node = head.next;  
        while (node != null){  
            Node<T> next = node.next;  
            node.element = null;  
            node.next = null;  
            node = next;  
        }  
        head.next  = null;  
        last = head;  
        size = 0;  
        modCount++;  
    }  
  
  
  
    private class Node<T>{  
        T element;  
        Node<T> next;  
  
        public Node(T data, Node<T> next){  
            this.element = data;  
            this.next = next;  
        }  
    }  
  
    @Override  
    public Iterator<T> iterator() {  
        return new SingleLinkedIterator();  
    }  
  
    private class SingleLinkedIterator implements Iterator<T>{  
  
        private Node<T> current = head.next;  
        private Node<T> preCurrent = head;  
        private Node<T> lastReturned;  
        private Node<T> preLastReturned;  
        private int currentModCount = modCount;  
  
        @Override  
        public boolean hasNext() {  
            return current != null;  
        }  
  
        @Override  
        public T next() {  
            if (modCount != currentModCount) {  
                throw new ConcurrentModificationException();  
            }  
            if (!hasNext()){  
                throw new NoSuchElementException();  
            }  
            T e = current.element;  
            lastReturned = current;  
            preLastReturned = preCurrent;  
            preCurrent = current;  
            current = current.next;  
            return e;  
        }  
  
        @Override  
        public void remove() {  
            if (modCount != currentModCount) {  
                throw new ConcurrentModificationException();  
            }  
            if (lastReturned == null)  
                throw new IllegalStateException();  
            preLastReturned.next = current;  
            preCurrent = preLastReturned;  
            lastReturned = preLastReturned = null;  
            size--;  
            modCount++;  
            currentModCount++;  
        }  
    }  
  
}
  • 双链表
public class LitGrassLinkedList<T> implements Iterable<T>{  
  
    //头指针  
    private Node<T> head;  
    //尾指针  
    private Node<T> tail;  
  
    private int size = 0;  
    private int modCount = 0;  
  
    public LitGrassLinkedList(){  
        doClear();  
    }  
  
    public void clear(){  
        doClear();  
    }  
  
    public int size(){  
        return size;  
    }  
  
    public void add(T e){  
        linkLast(e);  
    }  
  
    public void add(T e,int index){  
        checkPositionIndex(index);  
        if (index == size) {  
            linkLast(e);  
        }else {  
            linkBefore(e,node(index));  
        }  
    }  
  
    public T remove(int index){  
        checkElementIndex(index);  
  
        Node<T> removeNode = node(index);  
        removeNode.prev.next = removeNode.next;  
        removeNode.next.prev = removeNode.prev;  
        size--;  
        modCount++;  
        return removeNode.element;  
    }  
  
    public T get(int index){  
        checkElementIndex(index);  
        return node(index).element;  
    }  
  
    public void set(int index,T e){  
        checkElementIndex(index);  
        node(index).element = e;  
    }  
  
    private Node<T> node(int index){  
        if(index < (size >> 1)){  
            Node<T> p = head.next;  
            for (int i = 0; i < index; i++) {  
                p = p.next;  
            }  
            return p;  
        }else {  
            Node<T> p = tail.prev;  
            for (int i = size - 1; i > index; i--) {  
                p = p.prev;  
            }  
            return p;  
        }  
    }  
  
    private void linkLast(T e){  
        linkBefore(e,tail);  
    }  
  
    private void linkBefore(T e,Node<T> node){  
        Node<T> newNode = new Node<>(node.prev, e, node);  
        node.prev.next = newNode;  
        node.prev = newNode;  
        size++;  
        modCount++;  
    }  
  
    private void doClear(){  
        head = new Node<>(null,null,null);  
        tail = new Node<>(head,null,null);  
        head.next = tail;  
        size = 0;  
        modCount++;  
    }  
  
    private boolean isPositionIndex(int index){  
        return index >= 0 && index <= size;  
    }  
  
    private void checkPositionIndex(int index) {  
        if (!isPositionIndex(index))  
            throw new IndexOutOfBoundsException();  
    }  
  
    private void checkElementIndex(int index) {  
        if (!isElementIndex(index))  
            throw new IndexOutOfBoundsException();  
    }  
  
    private boolean isElementIndex(int index) {  
        return index >= 0 && index < size;  
    }  
  
    private class Node<T>{  
        private Node<T> prev;  
        private Node<T> next;  
        private T element;  
  
        public Node(Node<T> prev,T e,Node<T> next){  
            this.prev = prev;  
            this.next = next;  
            this.element = e;  
        }  
    }  
  
    @Override  
    public Iterator<T> iterator() {  
        return new LinkedIterator();  
    }  
  
    private class LinkedIterator implements Iterator<T>{  
  
        private Node<T> current = head.next;  
        private int currentModCount = modCount;  
  
        private Node<T> lastReturned;  
  
        @Override  
        public boolean hasNext() {  
            return current != tail;  
        }  
  
        @Override  
        public T next() {  
            if (modCount != currentModCount) {  
                throw new ConcurrentModificationException();  
            }  
            if (!hasNext()){  
                throw new NoSuchElementException();  
            }  
  
            lastReturned = current;  
            current = current.next;  
            return lastReturned.element;  
        }  
  
        @Override  
        public void remove() {  
            if (modCount != currentModCount) {  
                throw new ConcurrentModificationException();  
            }  
            if (lastReturned == null) {  
                throw new IllegalStateException();  
            }  
  
            lastReturned.prev.next = lastReturned.next;  
            lastReturned.next.prev = lastReturned.prev;  
            lastReturned = null;  
            size--;  
            modCount++;  
            currentModCount++;  
        }  
    }  
}
  • 循环链表
public class LitGrassCircleLinkedList<T> implements Iterable<T> {  
  
    //维护一个尾部指针  
    private Node<T> last;  
    private int size = 0;  
    private int modCount = 0;  
  
    public LitGrassCircleLinkedList() {  
        doClear();  
    }  
  
    public void clear(){  
        doClear();  
    }  
  
    public int size(){  
        return size;  
    }  
  
    private void doClear(){  
        if (last != null) {  
            Node<T> p = last.next;  
            while (p != last){  
                Node<T> next = p.next;  
                p.element = null;  
                p.next = null;  
                p = next;  
            }  
            last.next = null;  
            last.element = null;  
            last = null;  
            size = 0;  
            modCount++;  
        }  
    }  
  
    public void add(T e){  
        linkLast(e);  
    }  
  
    public void add(T e,int index){  
  
        checkPositionIndex(index);  
        if(index == size){  
            linkLast(e);  
        } else if (index == 0) {  
            Node<T> p = last;  
            linkLast(e);  
            last = p;  
        }else {  
            linkBefore(e,node(index - 1));  
        }  
    }  
  
    public T get(int index){  
        checkElementIndex(index);  
  
        return node(index).element;  
    }  
  
    public T remove(int index){  
        checkElementIndex(index);  
  
  
        if (index == 0){  
            if (size == 1) {  
                doClear();  
                size--;  
                modCount++;  
                return last.element;  
            }else {  
                Node<T> p = last.next;  
                last.next = last.next.next;  
                size--;  
                modCount++;  
                return p.element;  
            }  
        }else {  
            Node<T> node = node(index - 1);  
            Node<T> removeNode = node.next;  
            node.next = removeNode.next;  
            if(index == size - 1){  
                last = node;  
            }  
            size--;  
            modCount++;  
            return removeNode.element;  
        }  
  
    }  
  
    private void linkLast(T e){  
        Node<T> newNode = new Node<>(e, null);  
        if(last == null){  
            newNode.next = newNode;  
        }else {  
            newNode.next = last.next;  
            last.next = newNode;  
        }  
        last = newNode;  
        size++;  
        modCount++;  
    }  
  
    private void linkBefore(T e,Node<T> before){  
        Node<T> newNode = new Node<>(e, before.next);  
        before.next = newNode;  
        size++;  
        modCount++;  
    }  
  
    private Node<T> node(int index){  
        Node<T> p = last.next;  
        for (int i = 0; i < index; i++) {  
            p = p.next;  
        }  
        return p;  
    }  
  
  
    private class Node<T>{  
        private Node<T> next;  
        private T element;  
  
        public Node(T e,Node next){  
            this.element = e;  
            this.next = next;  
        }  
    }  
  
    private boolean isPositionIndex(int index){  
        return index >= 0 && index <= size;  
    }  
  
    private void checkPositionIndex(int index) {  
        if (!isPositionIndex(index))  
            throw new IndexOutOfBoundsException();  
    }  
  
    private void checkElementIndex(int index) {  
        if (!isElementIndex(index))  
            throw new IndexOutOfBoundsException();  
    }  
  
    private boolean isElementIndex(int index) {  
        return index >= 0 && index < size;  
    }  
  
    @Override  
    public Iterator<T> iterator() {  
        return new CircleLinkedIterator();  
    }  
  
    public Iterator<T> loopIterator(){  
        return new LoopIterator();  
    }  
  
    private class LoopIterator implements Iterator<T>{  
  
        private int currentModCount = modCount;  
        private Node<T> current = last.next;  
        private Node<T> preCurrent = last;  
        private Node<T> lastReturned;  
        private Node<T> preLastReturned;  
  
        @Override  
        public boolean hasNext() {  
            return size != 0;  
        }  
  
        @Override  
        public T next() {  
            if (modCount != currentModCount) {  
                throw new ConcurrentModificationException();  
            }  
            if (!hasNext()){  
                throw new NoSuchElementException();  
            }  
            T e = current.element;  
            lastReturned = current;  
            preLastReturned = preCurrent;  
            preCurrent = current;  
            current = current.next;  
            return e;  
        }  
  
        @Override  
        public void remove() {  
            if (modCount != currentModCount) {  
                throw new ConcurrentModificationException();  
            }  
            if (lastReturned == null)  
                throw new IllegalStateException();  
  
            if(size == 1){  
                doClear();  
                current = preCurrent = lastReturned = preLastReturned = null;  
            }else {  
                preLastReturned.next = current;  
                preCurrent = preLastReturned;  
                if (lastReturned == last) {  
                    last = preLastReturned;  
                }  
                lastReturned = preLastReturned = null;  
                size--;  
                modCount++;  
            }  
  
  
            currentModCount++;  
        }  
    }  
  
    private class CircleLinkedIterator implements Iterator<T>{  
  
        private int currentModCount = modCount;  
        private Node<T> current = last.next;  
  
        private Node<T> preCurrent = last;  
        private Node<T> lastReturned;  
        private Node<T> preLastReturned;  
        private int indexMark = 0;  
        @Override  
        public boolean hasNext() {  
            return indexMark < size;  
        }  
  
        @Override  
        public T next() {  
            if (modCount != currentModCount) {  
                throw new ConcurrentModificationException();  
            }  
            if (!hasNext()){  
                throw new NoSuchElementException();  
            }  
            T e = current.element;  
            lastReturned = current;  
            preLastReturned = preCurrent;  
            preCurrent = current;  
            current = current.next;  
            indexMark++;  
            return e;  
        }  
  
        @Override  
        public void remove() {  
            if (modCount != currentModCount) {  
                throw new ConcurrentModificationException();  
            }  
            if (lastReturned == null)  
                throw new IllegalStateException();  
            preLastReturned.next = current;  
            preCurrent = preLastReturned;  
            lastReturned = preLastReturned = null;  
            size--;  
            modCount++;  
            currentModCount++;  
        }  
    }  
}