自己实现简单的linkedlist 没有迭代器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自己实现简单的linkedlist 没有迭代器相关的知识,希望对你有一定的参考价值。

package demo;

import java.util.Collection;

public class MyLinkedList<E> {
    // 属性

    // 构造方法
    public MyLinkedList() {

    }

    public MyLinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }

    // 构建双向链表,首先要构建节点
    // 建立成员内部类节点,
    private static class Node<E> {
        E item; // 存储数据
        Node<E> next;// 下一个节点
        Node<E> prev; // 前一个节点

        public Node(Node<E> next, E item, Node<E> prev) {
            this.item = item;
            this.next = next;
            this.prev = prev;
        }
    }
    // 一个数组域存放数组,一个prev指向前一个节点的next 一个next指向下一个节点的prev.

    // 第一个节点
    private Node<E> first;
    // 最后一个节点
    private Node<E> last;
    // 数组个数
    private int size;

    // 将指定元素追加到此列表的末尾
    public boolean add(E e) {
        addLast(e);
        return true;
    }

    // 将节点连接到此列表的末尾
    void addLast(E e) {
        Node<E> l = last; // 首先找到最后一个元素
        Node<E> node = new Node<E>(null, e, l);// 根据传入的e创建一个新的节点next指向null
                                                // item存传入的e prev指向l;
        last = node; // 将刚刚新创建的节点node变为最后一个节点
        if (l == null) { // 如果最后一个节点null
            first = node; // 第一个节点就为node
        } else {
            l.next = node; // 将前一个节点的next指向下一个节点
        }
        size++; // size+1
    }

    public void addfirst(E e) {
        linkfirst(e);
    }

    // 在此列表中的指定位置插入指定的元素
    public void add(int index, E e) {
        checkRange(index);// 首先判断范围
        if (index == size) { // 如果插入的在最后一个就调用插入最后一个的方法
            addLast(e);
        } else { // 否则取到index位置对应的node元素,然后替换
            Node<E> l = index(index);
            addBeforeNode(e, l);
        }
    }

    // 在指定元素前插入元素
    private void addBeforeNode(E e, Node<E> l) {
        Node<E> preNode = l.prev;
        Node<E> newnode = new Node<>(l, e, preNode);
        if (preNode == null) {
            first = newnode;
        } else {
            preNode.next = newnode;
        }
        l.prev = newnode;
        size++;
    }

    // 查找index出的元素
    private Node<E> index(int index) {// 采用二分法查找

        if (index < (size / 2)) { // 首先判断index在前一半还是后一半的范围,然后找到index出的元素
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }

    void linkfirst(E e) {
        Node<E> l = first; // 首先找到第一个一个元素
        Node<E> node = new Node<E>(l, e, null);// 根据传入的e创建一个新的节点next指向null
                                                // item存传入的e prev指向l;
        first = node; // 将刚刚新创建的节点node变为最后一个节点
        if (l == null) { // 如果第一个节点null
            first = node; // 第一个节点就为node
        } else {
            l.prev = node; // 将前一个节点的next指向下一个节点
        }
        size++; // size+1
    }

    // 删除所有的元素
    public void clear() {
        for (Node<E> x = first; x != null;) {
            Node<E> next = x.next;
            x.item = null;
            x.prev = null;
            x.next = null;
            x = next;
        }
        first = last = null;
        size = 0;
    }

    // 判断是否越界
    private void checkRange(int index) {
        if (index < 0 && index > size)
            throw new IndexOutOfBoundsException("越界了");
    }

    // 返回列表中指定位置的元素
    public E get(int index) {
        checkRange(index);
        return index(index).item;
    }

    //
    private void addAll(Collection<? extends E> c) {
        // TODO Auto-generated method stub
    }

    // 返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。
    public int indexOf(Object o) {
        Node<E> n = first;
        int c = 0;
        while (n != null) {
            if (o != null) {
                if (o.equals(n.item))
                    return c;
            } else {
                if (n.item == null) {
                    return c;
                }
            }
            c++;
            n = n.next;
        }
        return -1;
    }
    //删除指定节点
    public E remove (int index){
        checkRange(index);
        return  unlink(index);
    }
    //删除指定对象
    public boolean remove(Object o){
        int index = indexOf(o);
        if(index<0){
            return false;
        }
        unlink(index);
        return true;
    }
    //删除index对应的节点的连接
    private E unlink(int index){
        Node<E> l = index(index);
        E item = l.item;
        Node<E> preNode = l.prev;
        Node<E> nextNode = l.next;
        if(preNode==null){
            first = nextNode;
        }else{
            preNode.next=nextNode;
            l.next=null;
        }
        if(nextNode==null){
            last = preNode;
        }else{
            nextNode.prev = preNode;
            l.prev=null;
        }
        size--;
        l.item=null;
        return item;
    }
}

LinkedList是基于双向链表实现的,
LinkedList和ArrayList的区别:
ArrayList基于数组实现,因此具有数组的特点:有序.元素可重复.插入慢.查找快
LinkedList 基于双向链表实现, 因此具有链表特带你 插入快、 查找慢的特性;

以上是关于自己实现简单的linkedlist 没有迭代器的主要内容,如果未能解决你的问题,请参考以下文章

ArrayList和LinkedList和Vactor的区别

ArrayList和LinkedList和Vactor的区别

LinkedList源码分析--jdk1.8

在 LinkedList 中向后移动的语法?

LinkedList 和 ArrayList 实现的区别? [复制]

LinkedList 源码分析