数组

        数组是一种线性表,用连续的内存空间来存放相同的类型的数据。

        1.1 数组是一种线性表

        线性表,元素之间的关系,可以连成一条线的就叫做线性表,它们的关系是简单的前后关系。比如常见的,链表,栈,队列等等

        非线性表,元素之间不是简单的前后关系,比如,树和图。

        1.2 连续的内存空间和相同类型的数据

         正是因为这两个限制,它才有堪称杀手级的特性,随机访问。但是这两个限制也让

         数组很多操作都变得非常低效,比如要想在数组中删除,插入一个数据,为了保证连续性 ,就要做大量的数据迁移工作

       1.3 数组低效的插入和删除操作。

         第一次学习数据结构的时候,老师和我说,链表和数组的区别是什么呢,链表的插入和删除效率比数组高。

         数组的查找效率更好(数组支持下标访问,根据下标随机访问的时间复杂度为O(1))。

         老师和我们说,为了保证内存空间的连续性,比如你在数组中插入一个元素,那么所有的数据都要往后移动一位。

         所以它的时间复杂度是o(n);当时也没怀疑老师的说法,也没去想想有没有什么解决方案,真是惭愧...

         现在静下心来想想,还真有解决办法。因为这里的问题就是:数据大规模的搬移工作。

         如果说,我们在插入数据的时候,直接将第n个位置上 的数组,移动到数组元素最后,把新元素直接放入第K个位置。

         这样时间复杂度就是o(1);

          

           如上图所示;

           再来看看删除操作

          删除一个数据,为了内存的连续性,也要搬移数据,不然就会出现空洞,内存就不连续了。

          实际上在某些特殊的场景下,我们不一定非得追求数组中,数据的连续性。如果我们将多次删除操作,集中到一起执行

          效率是不是会提高很多呢。

         现在要删除依次a,b,c这个三个元素,为了避免d,e,f,g,h这几个数据被移动三次,我可以先记录下已经删除的数据。

         每次删除的操作并不是真正的搬移数据,而是记录数据已经被删除。当数组没有更多的空间存储数据的时候,再触发一次

         真正的删除操作,这样就大大的减少了删除操作导致的数据搬移。

         1.4  数组的越界问题,很多高级语言都已经对这个进行包装了,数组越界会抛出异常。

         1.5 C#里面ArrayList,数组,List的区别。面试题常考。

         1.6 数组里面的连续存储空间对CPU来说是非常友好的,因为它可以借助CPU缓存机制,按照如果这个内存块被用到,则他下一个内存块也会有很大可能被用到的原则,所以CPU把数据加载到CPU的缓存的时候,会考虑把连续的空间一起加入缓存中。

         

posted @ 2018-11-19 23:11  GDOUJKZZ  阅读(176)  评论(0编辑  收藏  举报