老狗啃骨头之数据结构-数组和链表
摘要:
数组的优点是查找快遍历快;缺点是用的时候要先初始,不支持扩容,添加删除元素比较慢。适用于频繁查询,增删操作较少,对空间要求相对节约的场景。链表的优点是用的时候不需要初始,并可以随意增删元素,也没有长度限制;缺点是额外的指针域,会占用较多的空间,遍历起来也会相对数组更为耗时。适用于数据量相对较小,增删操作相对频繁的场景
数组
数组,是能存储相同类型变量,并将其组织成连续且有序集合的容器。我这样说,也是有点拧巴,给大家看一组图:

来感受下,这个盒子,大概就是数组的样子。根据这个盒子格格里要装的不同类型的数据,我们可以去定义它,整形数组、字符数组;当然格子里可以是任何抽象的事物,可以装个对象,奶牛数组、水果数组。
数组的形式也不拘于这么简简单单的一排,我们可以假定,数组的元素还可以是数组类型本身,我们可以看看这个东西:

这个横排排竖排排的格子柜是老中医的中药柜,我们把这一竖排看作一个数组对象,这个药柜整体来看其实就像是一个二维数组的体现,一横一竖两个维度,连续而有序。
我从网上扒来一个老古董,上了年岁的老药柜,来看一个细节:

原来这一横一竖定位到的盒子本身,竟然也是个“数组”对象!对,这个大概就是三位数组的样子,以此类推,一层一层的套下去,就是多维数组。
当然在计算机里,数组不可能是这个样子,但这些个盒子,可以近乎完美的诠释,数组这种数据结构。
在所有数据结构中,数组算是最基本的数据结构,我们来总结总结它的特点。
联想上边这些盒子柜子,我们根据这横横竖竖这些维度、根据他的排列次序去查找定位,快速又方便;但是如果想对这个位置上的元素进行操作,就得把它拿进来或放进去,并且数组有一个弊端,就是为了保证数组的连续性和有序性,在这个被操作元素位置之后的所有元素,都要跟着挪一挪;除此之外,数组还有个短板,就是一旦声明定义之后,就像这些个盒子柜子一样,长度大小都定了,不能随意扩容。
链表
链表是一类数据元素在逻辑上连续、物理上没有特别要求,链式存储的数据结构。链表一般由一系列数据结点组成,每个数据结点包括数据部分和指针部分。其中数据部分我们称之为数据域,指针部分保存着下一个元素存放的地址,我们称之为指针域。链表结构中数据元素的逻辑顺序是通过链表节点的指针链接次序来实现的。
我们来欣赏下咱们青藏高原的风景:

看这一列火车,就很像能描述链表的样子。每一节车厢就像一个数据块,车厢之间的接头就像是指针域一样,从这一节连到下一节;我们小时候都玩过小火车的玩具,是这样子的:

每一节其实都可以拆开,我们可以按照我们的喜好和需要随意链接组合,连成一串。但事实上,链表这种结构只强调逻辑上的连续,并不要求空间上的讲究,真实的样子可能更像下图:

当然,真实的计算机物理存储远比简笔画复杂得多。在这个图画所展示的组成结构中,我们不难发现,链表的节点增删其实相对数组,要变得简单容易的多得多,我们只要去操作他的指针指向,就可以达成目的,就像以下两张图:
删除节点:

增加节点:

同时也可很容易发现,由于物理位置的随意性,会导致链表遍历起来比较尴尬,只能通过一个节点一个节点,根据他们的指针域的指向,往下一个节点逐次进行,这个相对于数组来说,就要慢得多得多,这是由他们的结构特点和物理存储特性决定的。
总结
数组和链表,简单总结,二者各有优劣。
数组的优点是查找快、遍历快;缺点是用的时候要先初始、开辟存储空间,且不支持扩容,添加删除元素会比较慢。适用于频繁查询,增删操作较少,对空间要求相对节约的场景。
链表的优点是用的时候不需要去初始、不用先开辟空间,并可以随意增删元素,也没有长度限制;缺点是因为需要额外的指针域,会占用较多的存储空间,遍历起来也会相对数组更为耗时。适用于数据量相对较小,增删操作相对频繁的场景。
数组和链表都是基础、典型的数据结构,在实际使用过程中,可以根据其特性和场景需要进行选择,还可以根据其特性进行升级改造,例如多维数组、双向链表等,以便达到更好的计算操作效率。