LinkedList实现

来源:互联网 发布:lics算法 编辑:程序博客网 时间:2024/05/22 03:36

LinkedList实现

  本节给出LinkedList的实现,命名为MyLinkedList。采用普遍的双链表,与ArrayList相比,可以较快地进行插入和删除操作,只需要将元素的指针指向改变即可,实现常数次操作。保存该链表的首末段指针(引用),保证对头尾元素的访问为O(1),并且,如果已知访问元素的位置,就可以决定从哪个端点开始遍历,一定程度上补偿链表的访问速度问题,双端列表的简单结构如下图。

链表结构图

功能描述

  • MyLinkedList包含链表两端,大小以及一些常用方法;
  • Node类,用来描述链表节点,包含自身数据、指向下一个节点和上一个节点的指针,以及一些适当的构造方法;
  • LinkedListIterator类,该类实现了Iterator接口,可以作为内部类或嵌套类在MyLinkedList内部实现,提供next(), hasNext(0和remove()方法实现。

代码实现

package com.yam.base;import java.util.ConcurrentModificationException;import java.util.Iterator;import java.util.NoSuchElementException;/** * LinkedList简单实现 * @author: Ympery * @date: 2017/3/13 15:00. */public class MyLinkedList<AnyType> implements Iterable<AnyType> {    /**     * 链表长度     */    private int theSize;    /**     * 用于标记链表自构造起,对其的操作次数,防止并发错误     */    private int modCount = 0;    /**     * 整个链表的头结点     */    private Node<AnyType> beginMarker;    /**     * 整个链表的尾节点     */    private Node<AnyType> endMarker;    public MyLinkedList() { clear(); }    /**     * 清除链表,当链表为null时,只有头尾     */    public void clear() {        beginMarker = new Node<>(null, null, null);        endMarker = new Node<>(null, beginMarker, null);        beginMarker.next = endMarker;        theSize = 0;        modCount++;    }    /**     * 返回长度     * @return     */    public int size() { return theSize; }    /**     * 判断链表是否为空     * @return     */    public boolean isEmpty() { return theSize == 0; }    /**     * 在链表末端添加值     * @param x     * @return     */    public boolean add(AnyType x) {        add(size(), x);        return true;    }    /**     * 按索引位置添加值     * @param idx 位置     * @param x 添加的元素     */    public void add(int idx, AnyType x) {        addBefore(getNode(idx), x);    }    /**     * 按索引位置获取节点值     * @param idx     * @return     */    public AnyType get(int idx) {        return getNode(idx).data;    }    /**     * 按索引位置设置新值     * @param idx 索引     * @param newVal 值     * @return     */    public AnyType set(int idx, AnyType newVal) {        Node<AnyType> p = getNode(idx);        AnyType oldVal = p.data;        p.data = newVal;        return oldVal;    }    /**     * 按索引位置删除值     * @param idx     * @return     */    public AnyType remove(int idx) {        return remove(getNode(idx));    }    /**     * 删除指定节点     * @param p     * @return     */    private AnyType remove(Node<AnyType> p) {        p.prev.next = p.next;        p.next.prev = p.prev;        theSize--;        modCount++;        return p.data;    }    /**     * 在节点前插入节点     * @param p 指定节点(在此节点之前插入新节点)     * @param x 要插入的节点的值     */    private void addBefore(Node<AnyType> p, AnyType x) {        Node<AnyType> newNode = new Node<>(x, p.prev, p);        newNode.prev.next = newNode;        p.prev = newNode;        theSize++;        modCount++;    }    /**     * 按索引位置获取链表节点     * @param idx 索引位置     * @return     */    private Node<AnyType> getNode(int idx) {        Node<AnyType> p;        if (0 > idx || idx > size())            throw new IndexOutOfBoundsException();        // 判断查询位置在链表的前半部分        if (size() / 2 > idx) {            p = beginMarker.next;            for (int i = 0; i < idx; i++)                p = p.next;        }        // 判断查询位置在链表的后半部分        else {            p = endMarker;            for (int i = size(); i > idx; i--)                p = p.prev;        }        return p;    }    public Iterator<AnyType> iterator() {        return new LinkedListIterator();    }    /**     * MyLinkedList的迭代器,使用内部类实现     */    private class LinkedListIterator implements Iterator<AnyType> {        private Node<AnyType> current = beginMarker.next;        private int expectedModCount = modCount;        private boolean okToRemove = false;        @Override        public boolean hasNext() {            return current != endMarker;        }        @Override        public AnyType next() {            if (modCount != expectedModCount)                throw new ConcurrentModificationException();            if (!hasNext())                throw new NoSuchElementException();            AnyType nextItem = current.data;            current = current.next;            okToRemove = true;            return nextItem;        }        @Override        public void remove() {            if (modCount != expectedModCount)                throw new ConcurrentModificationException();            if (!okToRemove)                throw new IllegalStateException();            MyLinkedList.this.remove(current);            okToRemove = false;            expectedModCount++;        }    }    /**     * 链表节点     * @param <AnyType>     */    private static class Node<AnyType> {        public Node(AnyType d, Node<AnyType> p, Node<AnyType> n) {            data = d;            prev = p;            next = n;        }        /**         * 当前节点数据         */        public AnyType data;        /**         * 上一个节点的引用         */        public Node<AnyType> prev;        /**         * 下一个节点引用         */        public Node<AnyType> next;    }    /**     * 测试     * @param args     */    public static void main(String[] args) {        MyLinkedList<Character> chLinkList = new MyLinkedList<>();        char c = 'a';        for (int i = 0; i < 20; i++)            chLinkList.add(c++);        for (char ch : chLinkList)            System.out.print(ch + " ");        System.out.println("删除之前");        chLinkList.remove(10);        for (char ch : chLinkList)            System.out.print(ch + " ");        System.out.println("删除之后");        Iterator iterator = chLinkList.iterator();        System.out.println("采用迭代器遍历");        while (iterator.hasNext())            System.out.print(iterator.next() + " ");    }}
0 0
原创粉丝点击