本文主要对数组和链表进行讲解,给很多无法理解的小伙伴一个入口
数组
理解: 数组可以理解为一个大巴车,每个座位就是一个数组元素,每个座位都有一个编号,你可以通过编号直接来访问特定的座位,如果座位不够用,你只能换一个更大的大巴车,让原来的乘客去乘坐新的大巴车。
定义:数组是一种线性数据结构,用于存储固定大小的相同类型元素的集合。在 Java 中,数组的大小在创建时就需要确定,并且在整个生命周期内通常保持不变。
特点:内存连续性-数组在内存中占用连续的存储空间,通过索引可以快速访问数组中的任意元素。固定大小-数组的大小在创建时确定,一旦确定就不能动态改变。如果需要改变数组大小,通常需要创建一个新的数组并将原数组元素复制过去。相同类型元素-数组只能存储相同类型的元素,例如 int 数组只能存储 int 类型的数据。
操作:由于数组在内存中是连续存储的,通过索引访问元素的时间复杂度为O(1) ,即无论数组的大小如何,访问任意元素的时间都是恒定的。在数组中插入或删除元素通常需要移动大量元素,时间复杂度为 O(n),其中n是数组的长度。例如,在数组中间插入一个元素,需要将插入位置之后的所有元素向后移动一位。
场景:数组适用于需要频繁随机访问元素,且元素数量相对固定的场景
链表
理解: 链表可以理解为一个火车,每个车厢就是一个链表节点,每个车厢都有一个编号,你可以通过编号来访问特定的车厢;找到这个车厢,你需要知道车厢的上一个车厢编号或者下一个车厢的编号,如果人数比较多车厢不够用,你可以在这个车厢后面或者前面插入一个新的车厢,让新来的乘客去新的车厢。
定义:链表是一种线性数据结构,由一系列节点组成,每个节点包含数据元素和指向下一个节点的引用(在双向链表中还包含指向前一个节点的引用)。
特点:内存离散性-链表的节点在内存中可以分散存储,通过引用建立节点之间的逻辑联系。动态大小-链表的大小可以动态改变,在需要添加或删除节点时,只需要修改相关节点的引用即可。灵活插入和删除-相比于数组,链表在插入和删除节点时更加灵活,不需要移动大量元素。
操作:链表不支持随机访问,要访问链表中的某个节点,必须从链表的头节点开始,依次遍历链表,直到找到目标节点。因此,访问链表中第 i个节点的时间复杂度为O(i) ,平均时间复杂度为O(n),其中n是链表的长度。在链表中插入或删除节点相对较为高效,只需要修改相关节点的引用即可。如果已经知道要操作的节点位置,插入和删除操作的时间复杂度为 O(1)。但如果需要先遍历链表找到要操作的节点,平均时间复杂度为O(n)。
场景:链表适用于需要频繁进行插入和删除操作,且不需要随机访问元素的场景。