从零开始学java(25)--- 一些简单的数据结构与LinkedList

本文是Day15的学习笔记,主要讲解数据结构的基础知识,包括数组、链表、队列和栈的概念及其特点。接着深入探讨了LinkedList,介绍了其作为链表实现的List接口,在添加、删除和获取元素上的特性和方法。强调了LinkedList在数据频繁增删场景下的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Day15

今天了解一些简单的数据结构和学习LinkedList的有关知识。

1.数据结构与算法

什么是数据结构?

Sartaj Sahni在他的《数据结构、算法与应用》一书中称:“数据结构是数据对象,以及存在于该对象的实例合组成实例的数据元素之间的各种联系。这些联系可以通过定义相关的函数来给出。”他将数据对象(data object)定义为“一个数据对象是实例或值的集合”。

Clifford A.Shaffer在《数据结构与算法分析》一书中的定义是:“数据结构是 ADT(抽象数据类型Abstract Data Type) 的物理实现。”

大话数据结构:数据结构是相互之间存在一种或多种特定关系的数据元素的集合。

什么是算法?

算法是解决问题步骤的有限集合,通常用某一种计算机语言进行伪码描述。通常用时间复杂度和空间复杂度来衡量算法的优劣。

算法的五大特征:输入、输出、有穷性、确定性、可行性。
输入:零个或多个输入。
输出:一个或多个输出。
有穷性:有限步骤后在可接受时间内完成。
确定性:每个步骤都有确定含义,无二义性。
可行性:每一步都是可行的。

算法设计要求:正确性、可读性、健壮性、时间效率高和存储低。
正确性:有输入输出,无二义性,有正确答案。
可读性:方便阅读。
健壮性:输入不合法能处理
时间效率高和存储低:时间空间复杂度越低越好。

1.数组

数组是相同数据类型的元素按一定顺序排列的集合,是一块连续的内存空间。
特点:我们都知道数组中的元素在内存中连续存储的,可以根据是下标快速访问元素,因此,查询(get和set)速度很快,时间上都是O(1)的,然而插入和删除(add和remove)时,需要对元素移动空间,比较慢,操作时间上都是O(N)的。

Java中,Array就是数组,此外,ArrayList使用了数组Array作为其实现基础,它和一般的Array相比,最大的好处是,我们在添加元素时不必考虑越界,元素超出数组容量时,它会自动扩张保证容量。

Vector和ArrayList相比,主要差别就在于多了一个线程安全性,但是效率比较低下。如今java.util.concurrent包提供了许多线程安全的集合类(比如 LinkedBlockingQueue),所以不必再使用Vector了。

数组使用场景:频繁查询,很少增加和删除的情况。

2.链表

链表是一种非连续、非顺序的结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的,链表由一系列结点组成。
Java中,LinkedList 使用链表作为其基础实现。

特点:元素可以不连续内存中,是以索引将数据联系起来的,当查询(get和set)元素的时候需要从头开始查询,操作时间上都是O(N)的,而且需要额外的空间存储指向其他数据地址的项。,所以效率比较低。然而添加和删除(add和remove)的只需要修改索引就可以了,操作时间上都是O(1)的。

查找操作对于未排序的数组和链表时间上都是O(N)。

使用场景:少查询,需要频繁的插入或删除情况

3.队列

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端进行删除操作,而在表的后端进行插入操作,亦即所谓的先进先出(FIFO)。

特点:先进先出,

Java中,LinkedList实现了Deque,可以做为双向队列(自然也可以用作单向队列)。另外PriorityQueue实现了带优先级的队列,亦即队列的每一个元素都有优先级,且元素按照优先级排序。

使用场景:多线程阻塞队列管理非常有用

4.栈

栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。它体现了后进先出(LIFO)的特点。

特点:先进后出。

Java中,Stack实现了这种特性,但是Stack也继承了Vector,所以具有线程安全线和效率低下两个特性,最新的JDK8中,推荐用Deque来实现栈,比如:

使用场景:实现递归以及表示式

5.数组与链表的区别

数组连续,链表不连续(从数据存储形式来说)

数组内存静态分配,链表动态分配

数组查询复杂度0(1),链表查询复杂度O(n)

数组添加或删除,复杂度o(n),链表添加删除,复杂度O(1)

数组从栈中分配内存。链表从堆中分配内存。

6.集合

集合是指具有某种特定性质的具体的或抽象的对象汇总成的集体,这些对象称为该集合的元素,其主要特性是元素不可重复。

在Java中,HashSet体现了这种数据结构,而HashSet是在MashMap的基础上构建的。LinkedHashSet继承了HashSet,使用HashCode确定在集合中的位置,使用链表的方式确定位置,所以有顺序。TreeSet实现了SortedSet 接口,是排好序的集合(在TreeMap 基础之上构建),因此查找操作比普通的Hashset要快(log(N));插入操作要慢(log(N)),因为要维护有序。

2.LinkedList

LinkedList也是List接口的实现类,与ArrayList不同之处是采用的存储结构不同,ArrayList的数据结构为线性表,而LinkedList数据结构是链表。链表数据结构的特点是每个元素分配的空间不必连续、插入和删除元素时速度非常快、但访问元素的速度较慢。

其内部实现是一个双向(不循环)的链表

优点:对数据经常增加或删除,性能优于ArrayList
缺点:检索数据时不如ArrayList

LinkedList类每个结点用内部类Node表示,LinkedList通过first和last引用分别指向链表的第一个和最后一个元素,当链表为空时,first和last都为NULL值。LinkedList数据结构如下图所示:

在这里插入图片描述

1.在LinkedList中添加元素

LinkedList提供了多个添加元素的方法:

●boolean add(E e)

在链表尾部添加一个元素,如果成功,返回true,否则返回false。

●void addFirst(E e)

在链表头部插入一个元素。

●addLast(E e)

在链表尾部添加一个元素。

●void add(int index, E element)

在指定位置插入一个元素。

2.从LinkedList中删除元素

LinkedList提供了多个删除元素的方法:

●boolean remove(Object o)

从当前链表中移除指定的元素。

● E remove(int index)

从当前链表中移除指定位置的元素。

● E removeFirst()

从当前链表中移除第一个元素。

● E removeLast()

从当前链表中移除最后一个元素。

● E remove()

从当前链表中移除第一个元素,同removeLast()相同。

3.从LinkedList中获取元素

LinkedList提供了多个获取元素的方法:

● E get(int index)

从当前链表中获取指定位置的元素。

● E getFirst()

从当前链表中获取第一个元素。

● E getLast()

从当前链表中获取最后一个元素。

4.LinkedList的遍历方法

LinkedList可以通过迭代器、foreach语句、for循环语句等方法遍历集合的所有元素。

foreach语句效率最高,其次是迭代器,效率最差的是for循环。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值