今天跟大家分享的是迈克的<Beat It>,这是一首摇滚歌曲,听起来有点亢奋,不过其主题却是劝大家"少打架、多读书"。
本文主要跟大家分享一下数组和链表两种内存组织类型的异同,帮助大家正确理解好这两种数据结构并合理应用。
数组---一种有序、连续且有着相同元素的存储结构。
相同的元素类型;
依次连续顺序存放;
通过下标可以直接访问。
链表---一种不一定有序、不一定连续、不一定相同元素的存储结构。
元素不一定相同,只需要存在链接信息;
不需要内存连续;
非下标访问,通过链接信息遍历。
相同点比较少,两者都是内存数据的一种组织方式,数组通过连续相同元素分配的特点来进行节点的访问,而对于链表是通过链接关系(一般通过指针链接)来进行索引访问。(下面所有的数组项和链表项都统一叫节点) 相同点相对比较少,不然其中一方必定替代另外一方,所以这里重点谈谈不同点: 通过前面两者的特点我们知道,数组属于连续分配,一般都在定义的时候分配给定的大小,而链表却可以实现动态的节点插入和移除,这样对于一些内存利用空间多变的情况,使用链表会带来更多的灵活度和内存的利用率。如下图所示:
如果分配的数组之前仅仅只有7个节点空间,当需要插入7节点的时候,需要把所有的内存copy到一个更大的内存空间,然后再把7插入。
对于链表其实就不存在扩大容量的问题,如果空间足够且指针能够索引到,便可以"无限"扩充。 在含有Cache的系统中,由于CPU的访问速度相对普通内存而言不在一个数量等级,为了不拖累CPU都会在其中间通过Cache来作为一个缓冲,可以大大提高CPU访问主存的速度。
那么数组作为连续的内存组织方式,更容易被同时加载到Cache中从而提高CPU对内存数据的命中,并提高运算速度和效率。 这样就很明显了,数组通过下标可以直接访问到对应的节点,而链表需要通过头指针不断的进行遍历从而找到对应的节点。例如:我们想直接访问数组的第三个节点,直接通过Array[2]即可,而对于链表则通过头指针,不断的找下一个节点最终找到第三个节点的位置,这样链表的时间复杂度就比数组大。
对于数组由于其固定的顺序存储格式特点所以直接可以通过下标访问,然而对于链表的不连续性,其每个节点必须要存储其前驱或者后继的链接信息,这样就需要使用额外的内存空间进行信息保存,当节点比较多时可是一笔不小的内存开支。
一问到数组和链表的应用,大家一般都会想到一句话:"查询修改用数组,插入删除用链表",那么bug菌就在这里跟大家分析分析这句话:
上图数组在第四个元素后面插入一个节点,这样需要把4,5,6节点依次向后面移动一个节点,然后把新的元素加入。
上图链表中在4个位置插入一个新节点,首先需要通过遍历知道第四个节点,然后直接通过改变指针进行新节点的链表插入。
上图数组在数据1后面插入一个新的节点,首先数组需要遍历知道数据1,然后移动3,5,6数据节点,并插入新节点。
上图数组在数据1后面插入一个新的节点,首先链表需要遍历知道数据1,然后直接插入新节点。 看完本文的小伙伴应该对数组和链表有了更加清晰的认识,其实这些对比对于以后大家进行一些代码上的优化和设计是非常有帮助的,大家好好体会一下!
好了,这里是公众号:“最后一个bug”,一个为大家打造的技术知识提升基地。同时非常感谢各位小伙伴的支持,我们下期精彩见!
如果有想加入公众号群聊共同讨论技术的小伙伴可以添加下方bug菌微信!
推荐好文 点击蓝色字体即可跳转
☞【C进阶】二级指针这个问题被问好几遍!该终结了!
☞【C进阶】这种地方别再强制类型转化了,来告诉你个小技巧!
☞【算法】"暴力"字符匹配算法的C语言实现
☞【重磅】剖析MCU的IAP升级软件设计(设计思路篇)
☞【算法】高效"KMP"字符匹配算法就这么简单
☞【典藏】自制小型GUI界面框架(设计思想篇)
☞【C进阶】听说用 “ 逗号表达式 ” 仅仅为了秀技?
☞深度剖析"bit序"与"字节序"
☞【进阶】嵌入式编程技法之"数据驱动编程"