数据结构——链表List、ArrayList、LinkedList


title: '数据结构——链表List、ArrayList、LinkedList ’
date: 2019-11-16 10:42:41
categories:

  • 数据结构
    tags:
  • 数据结构
  • 链表

抽象数据类型ADT

  • 是带有一组操作的一些对象的集合

一种特别的抽象类型——表ADT

什么是一个表呢?

最简单的一个整数表 -> 由一群整数构成的一个数组,可以看做是一张表

//表的简单数组实现
int[] arr = new int[10];
...
//对一个表的扩容
int[] newArr = new int[arr.length*2];
for(int i=0;i<arr.length;i++){
    newArr[i] = arr[i];
}
arr =newArr;

数组的实现是线性执行的,对其中的查找操作也是常数时间,但是插入和删除却潜藏着昂贵的开销。两种情况最坏的情况都是O(N)

简单链表

于是为了避免插入和删除的开销就有了,链表的出现。链表是由一个个节点组成的,并且不限制需要存储在一段连续的内存中。

节点

每一个节点均含有一个表元素、一个包含了后继节点的链Link。

//链表节点
LinkNode class{
    Object var;
    LinkNode next;
}

对于链表中节点的删除与插入,只需要常数时间。

首先找到要删除的节点位置或者要插入的节点位置

删除 该节点的前一个节点,指向该节点的后继节点就可以了

插入 找到插入节点的前一个节点,将前一个节点的后继节点用该节点指向,将前一个节点指向该节点

双链表

对于单链表的不足之处在于,对尾节点的删除,需要先找到最后节点的项,把他改为next链改为null,然后再更新持有最后节点的链。但是在经典链表中,每个节点均存储的是下一个节点,并不提供最后一个节点的前驱节点的任何信息。

<mark>单链表的删除需要靠辅助节点,而双向链表则可以直接删除</mark>

对于此,就想到了双向链表,让每一个节点持有一个指向它在表中的前驱节点的链。

JAVA中 Collections API中的表

集合的概念在java中用Collection接口来抽象,它存储一组类型相同的对象

//源码参考
public interface Collection<E> extends Iterable<E> {
 	int size();
     boolean isEmpty();
    boolean contains(Object o);
    Iterator<E> iterator(); //该方法继承于Iterable接口内的Iterator方法
    boolean add(E e);
    boolean remove(Object o);
}

Collection接口对Iterator接口进行了扩展,实现Iterator接口中那些类拥有增强的for循环。

//Iterator接口
public interface Iterator<E> {
    boolean hasNext(); 
    E next();
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

List接口、ArrayList类、LinkedList类

List接口 既是表的抽象,他继承了Collection

public interface List<E> extends Collection<E> {
     int size();
    boolean isEmpty();
    boolean contains(Object o);
    Iterator<E> iterator(); 
    Object[] toArray();

    
    E get(int index);
    E set(int index, E element);
    void add(int index, E element);
    E remove(int index);
    
    / ** 
        *从列表中的指定位置开始,以正确的
        *顺序返回列表中元素的列表迭代器。
        *指定的索引表示首次调用{@link ListIterator#next next}将返回的第一个元素。 
        *初次调用{@link ListIterator#previous previous}*返回具有指定索引减一的元素。 
        * * @param index从列表迭代器返回的第一个元素的索引(通过调用{@link ListIterator#next next}* @在此列表中的元素上返回列表迭代器(按适当的顺序) ,从列表中的指定位置开始
        * @throws IndexOutOfBoundsException如果索引超出范围
        *{@code index <0 || index> size()}* /
    ListIterator<E> listIterator(int index); 

ArrayList和LinkedList是对List的两种实现

ArrayList 单链表

  • 是一种可增长的数组实现

  • 优点在于,对get和set的调用花费常数时间

  • 缺点是add和remove的代价昂贵

ArrayList的实现与分析

LinkedList 双链表

  • 是一种双链表的实现
  • 优点在于,add和remove的开销小
  • 并且提供了addFirst、removeFirst、addLast、removeLast、getFirst、getLast等方法
  • 缺点则是他不容易进行索引,对get的调用则是昂贵的

未完待续。。。

全部评论

相关推荐

点赞 评论 收藏
分享
ProMonkey2024:5个oc?厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了(别的帖子偷来的,现学现卖😋)
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务