1. 程式人生 > 實用技巧 >資料結構雙向連結串列 DoublyLinkedList

資料結構雙向連結串列 DoublyLinkedList

package datastructures.linked;

import java.util.Iterator;

/**
 * @author warriorg
 */
public class DoublyLinkedList<T> implements Iterable<T> {
    private int size = 0;
    private Node<T> head = null;
    private Node<T> tail = null;

    class Node<T> {
        T data;
        Node<T> prev;
        Node<T> next;

        Node(T data, Node<T> prev, Node<T> next) {
            this.data = data;
            this.prev = prev;
            this.next = next;
        }

        @Override
        public String toString() {
            return "[" + prev + "|" + data + "|" + next + "]";
        } 
    }

    public T peek() {
        return head == null ? null : head.data;
    }


    public Boolean add(T item) {
        addLast(item); 
        return true; 
    }

    public void addFirst(T item) {
        final Node<T> first = head;
        final Node<T> node = new Node<>(item, null, head);
        head = node;
        if (first == null) {
            tail = node;
        } else {
            first.prev = node;
        }
        size++;
    }

    public void addLast(T item) {
        final Node<T> prev = tail; 
        final Node<T> node = new Node<>(item, prev, null);
        tail = node;
        if (prev == null) {
            head = node;
        } else {
            prev.next = node;
        }
        size++;
    }

    public void clear() {
        for (Node<T> curr = head; curr != null;) {
            Node<T> next = curr.next;
            curr.data = null;
            curr.prev = null;
            curr.next = null;
            curr = next;
        }

        head = tail = null;
        size = 0;
    }

    public T get(int index) {
        checkElementIndex(index);

        Node<T> curr = head;
        for (int i = 0; i < size; i++) {
            if (index == i) {
                return curr.data;
            }
            curr = curr.next;            
        }
        return null;
    }

    public boolean remove(T item) {
        return true;
    }

    public int size() {
        return size;
    }

    private void checkElementIndex(int index) {
        if (!(index > 0 && index < size)) {
           throw new IndexOutOfBoundsException(); 
        }
    }


    @Override
    public Iterator<T> iterator() {
        return new Iterator<T>() {
            private Node<T> curr = head;

            @Override
            public boolean hasNext() {
                return curr != null;
            }

            @Override
            public T next() {
                T data = curr.data;
                curr = curr.next;
                return data;
            }

            @Override
            public void remove() {

            }
        };
    }
}