算法学习-数组与链表

数据的逻辑结构分类:

  • 线性的:就是连成一条线的结构,例如 数组,链表,队列等
  • 非线性的:数据间的关系非线性,例如,堆,树,图等

数组

概念; 数组是一个有限的,类型相同的数据的集合,在内存中是一段连续的内存区域

数组.png
  • 数组的下标是从0开始的,上图数组中有6个元素,对应着下标依次是0、1、2、3、4、5,同时,数组里面存的数据的类型必须是一致的。
  • 数组中全部元素是“连续”的存储在一块内存空间中
数组的访问:

数组在访问操作中有着独特的性能优势,因为‘数组支持随机访问的’,也就是可以通过下标随机访问数组中的任何一个元素,其原理是因为数组元素的存储时连续的,所以我们可以通过数组内存空间的地址加上元素偏移量计算出某一个元素内存地址
数组【n】的地址=数组内存空间的首地址+每个元素大小,通过这个公式,数组中通过下标去访问数据时并不需要遍历整个数组,因此数组的访问时间是o(1)

备注:当然这里需要注意,如果不是通过下标去访问,而是通过内容去查找数组中的元素,则时间复杂度不是O(1),极端的情况下需要遍历整个数组的元素,时间复杂度可能是O(n),当然通过不同的查找算法所需的时间复杂度是不一样的。

数组的插入与删除:

同样是因为数组元素的连续性要求,所以导致数组在插入的删除元素比较低(要在数组中间插入一个新元素,就必须要将相邻的后面的元素全部往后移动一个位置,留出空位给这个新元素)如果新元素是插入在数组的最开头位置,那整个原始数组都需要向后移动一位,此时的时间复杂度为最坏情况即O(n),如果新元素要插入的位置是最末尾,则无需其它元素移动,则此时时间复杂度为最好情况即O(1),所以平均而言数组插入的时间复杂度是O(n)
数组的删除与数组的插入是类似的

链表

概念:链表是一种物理存储单元上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的,一般用于插入与删除较为频繁的场景


image.png

上图是“单链表”示例,链表并不需要数组那样的连续空间,它只需要一个个零散的内存空间即可,因此对内存空间的要求也比数组低。
链表的每一个节点通过“指针”链接起来,每一个节点有2部分组成,一部分是数据(上图中的item),另一部分是后继指针(用来存储后一个节点的地址),在这条链中,最开始的节点称为Head,最末尾节点的指针指向NULL。

链表也分为好几种,只有一个指针指向后续的一个节点,这个链表称为:单向链表,除此之外还有双项链表,循环链表
双向链表:


image.png

双向链表与单向链表的区别是前者是2个方向都有指针,后者只有1个方向的指针。双向链表的每一个节点都有2个指针,一个指向前节点,一个指向后节点。双向链表在操作的时候比单向链表的效率要高很多,但是由于多一个指针空间,所以占用内存也会多一点。

循环链表:
循环链表就是一种特殊的单向链表,只不过在单向链表的基础上,将尾节点的指针指向了Head节点,使之首尾相连。

image.png

  • 链表的访问
    链表的优势并不在与访问,因为链表无法通过首地址和下标去计算出某一个节点的地址,所以链表中如果要查找某个节点,则需要一个节点一个节点的遍历,因此链表的访问时间复杂度为O(n)

  • 链表的插入与删除
    也正式因为链表内存空间是非连续的,所以它对元素的插入和删除时,并不需要像数组那样移动其它元素,只需要修改指针的指向即可。

你可能感兴趣的:(算法学习-数组与链表)