双向链表实现List

Posted blogfyang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双向链表实现List相关的知识,希望对你有一定的参考价值。

双向链表实现List

话不多说上代码-_-
    import java.util.Iterator;

public class LinkedList<T> implements Iterable<T> {
    private LinkedList.Node<T> head;
    private LinkedList.Node<T> tail;
    private int size;

    public LinkedList() {
        LinkedList.Node<T> n = new LinkedList.Node();
        this.head = n;
        this.tail = n;
    }

    @SafeVarargs
    public LinkedList(T... ts) {
        LinkedList.Node<T> n = new LinkedList.Node();
        this.head = n;
        this.tail = n;
        Object[] var3 = ts;
        int var4 = ts.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            T t = var3[var5];
            this.add(t);
        }

    }

    public void add(T t) {
        LinkedList.Node n;
        for(n = this.head; null != n.next; n = n.next) {
        }

        LinkedList.Node<T> newNode = new LinkedList.Node(t);
        n.next = newNode;
        newNode.last = n;
        this.tail = newNode;
        ++this.size;
    }

    public void add(int index, T t) {
        if (index < 0) {
            throw new LinkedList.LinkedListIndexOutOfBoundException();
        } else {
            LinkedList.Node<T> n = this.head;

            for(int i = 0; i < index && null != n; ++i) {
                n = n.next;
            }

            if (null != n) {
                LinkedList.Node<T> _next = n.next;
                n.next = new LinkedList.Node(t);
                n.next.last = n;
                if (null != _next) {
                    n.next.next = _next;
                    _next.last = n;
                } else {
                    this.tail = n.next;
                }
            } else {
                this.tail.next = new LinkedList.Node(t);
                this.tail.next.last = this.tail;
            }

            ++this.size;
        }
    }

    public void addFirst(T t) {
        LinkedList.Node<T> first = this.head.next;
        this.head.next = new LinkedList.Node(t);
        if (null != first) {
            this.head.next.next = first;
            first.last = this.head.next;
        } else {
            this.head.next.last = this.head;
            this.tail = this.head.next;
        }

        ++this.size;
    }

    public T get(int index) {
        LinkedList.Node<T> n = null;
        int _index;
        if (index < 0) {
            _index = Math.abs(index);
            n = this.tail;

            for(int i = 0; i < _index - 1 && null != n; ++i) {
                n = n.last;
            }
        } else {
            n = this.head.next;

            for(_index = 0; _index < index && null != n; ++_index) {
                n = n.next;
            }
        }

        return n != null ? n.getT() : null;
    }

    public int indexOf(T t) {
        if (this.size == 0) {
            return -1;
        } else {
            LinkedList.Node<T> n = this.head;
            int index = -1;

            do {
                if ((n = n.next) == null) {
                    return -1;
                }

                ++index;
            } while(n.getT() == null || !n.getT().equals(t));

            return index;
        }
    }

    public int lastIndexOf(T t) {
        if (this.size == 0) {
            return -1;
        } else {
            LinkedList.Node<T> n = this.tail;
            int _index = 1;
            if (n.getT().equals(t)) {
                return this.size - 1;
            } else {
                do {
                    if ((n = n.last) == null) {
                        return -1;
                    }

                    ++_index;
                } while(n.getT() == null || !n.getT().equals(t));

                return this.size - _index;
            }
        }
    }

    public T removeFirst() {
        LinkedList.Node<T> n = this.head.next;
        if (null != n) {
            this.head.next = n.next;
            if (null == n.next) {
                this.tail = this.head;
            } else {
                n.next.last = this.head;
            }

            --this.size;
            return n.getT();
        } else {
            return null;
        }
    }

    public T removeLast() {
        if (this.size == 0) {
            return null;
        } else {
            LinkedList.Node<T> n = this.tail;
            if (n != null) {
                n.last.next = null;
                --this.size;
                return n.getT();
            } else {
                return null;
            }
        }
    }

    public T remove(int index) {
        LinkedList.Node n;
        int _index;
        if (index < 0) {
            _index = Math.abs(index);
            n = this.tail;

            for(int i = 0; i < _index - 1 && null != n; ++i) {
                n = n.last;
            }
        } else {
            n = this.head;

            for(_index = 0; _index <= index && null != n; ++_index) {
                n = n.next;
            }
        }

        if (n == null) {
            return null;
        } else {
            if (null != n.next) {
                n.next.last = n.last;
            }

            if (null != n.last) {
                n.last.next = n.next;
            }

            --this.size;
            return n.getT();
        }
    }

    public void concat(LinkedList<T> ll) {
        this.size += ll.size;
        this.tail.next = ll.head.next;
        if (null != this.tail.next) {
            ll.head.next.last = this.tail;
        }

        this.tail = ll.tail;
    }

    public void set(int index, T t) {
        if (this.size == 0) {
            throw new LinkedList.LinkedListEmptyException();
        } else {
            LinkedList.Node n;
            int _index;
            if (index < 0) {
                _index = Math.abs(index);
                n = this.tail;

                for(int i = 0; i < _index - 1 && n != null; ++i) {
                    n = n.last;
                }
            } else {
                n = this.head;

                for(_index = 0; _index <= index && n != null; ++_index) {
                    n = n.next;
                }
            }

            if (null != n && n != this.head) {
                n.setT(t);
            } else {
                throw new LinkedList.LinkedListIndexOutOfBoundException();
            }
        }
    }

    public Object[] toArray() {
        Object[] objs = new Object[this.size];
        int i = 0;

        for(LinkedList.Node n = this.head.next; n != null; n = n.next) {
            objs[i++] = n.getT();
        }

        return objs;
    }

    public void clear() {
        this.head.next = null;
        this.tail = this.head;
        this.size = 0;
    }

    public T pop() {
        return this.removeLast();
    }

    public void push(T t) {
        this.addFirst(t);
    }

    public int size() {
        return this.size;
    }

    public String toString() {
        if (this.isEmpty()) {
            return "[]";
        } else {
            StringBuilder buff = new StringBuilder("[");
            LinkedList.Node n = this.head;

            while((n = n.next) != null) {
                buff.append(n.getT()).append(", ");
            }

            buff.deleteCharAt(buff.length() - 1).deleteCharAt(buff.length() - 1).append("]");
            return buff.toString();
        }
    }

    public boolean isEmpty() {
        return null == this.head.next;
    }

    public T getFirst() {
        return this.head.getT();
    }

    public T getLast() {
        return this.tail.getT();
    }

    public LinkedList<T> subList(int start, int end) {
        if (start >= end) {
            throw new LinkedList.LinkedListNoSuchElementException();
        } else if (end >= this.size) {
            throw new LinkedList.LinkedListIndexOutOfBoundException();
        } else if (start < 0) {
            throw new LinkedList.LinkedListIndexOutOfBoundException();
        } else {
            LinkedList<T> ll = new LinkedList();

            for(int i = start; i < end; ++i) {
                ll.add(this.get(i));
            }

            return ll;
        }
    }

    public Iterator<T> iterator() {
        return new Iterator<T>() {
            private int cursor = 0;

            public boolean hasNext() {
                return this.cursor != LinkedList.this.size;
            }

            public T next() {
                if (this.cursor == LinkedList.this.size) {
                    throw new LinkedList.LinkedListNoSuchElementException();
                } else {
                    return LinkedList.this.get(this.cursor++);
                }
            }
        };
    }

    private static class LinkedListEmptyException extends RuntimeException {
        public LinkedListEmptyException() {
            super("List is Empty!");
        }
    }

    private static class LinkedListIndexOutOfBoundException extends RuntimeException {
        public LinkedListIndexOutOfBoundException() {
            super("Index Error!");
        }
    }

    private static class LinkedListNoSuchElementException extends RuntimeException {
        private LinkedListNoSuchElementException() {
        }
    }

    static class Node<T> {
        public LinkedList.Node<T> next;
        public LinkedList.Node<T> last;
        private T t;

        public Node() {
        }

        public Node(T t) {
            this.t = t;
        }

        public T getT() {
            return this.t;
        }

        public void setT(T t) {
            this.t = t;
        }
    }
}

以上是关于双向链表实现List的主要内容,如果未能解决你的问题,请参考以下文章

Linux利用list_head结构实现双向链表

数据结构之带头结点的循环双向链表详细图片+文字讲解

双向链表/list

List双向链表容器

在双向链表中的旧链表之后添加新链表

Redis系列:数据结构List双向链表LPUSHLPOPRPUSHRPOPLLEN命令