文章来源:http://blog.seclibs.com/%e6%95%b0%e6%8d%ae%e7%bb%93%e6%9e%84%e4%b9%8b%e6%95%b0%e7%bb%84/算法
在说数组以前我们先明确两个概念,什么是线性表,什么是非线性表编程
顾名思义,线性表就是把数据排成一条,每一个数据只有先后两种状况,常见的线性表有数组、链表、队列、栈等数组
那非线性表就更好理解了,数据不是按照一条线来排列的,每一个数据并不仅有先后两个方向,常见的有二叉树、堆、图等数据结构
明白了这个概念以后,我们再来讲数组,什么是数组?数据结构和算法
数组不只是大多数编程语言中的一个数据类型,它更是一个最基础的数据结构。编程语言
数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具备相同类型的数据。学习
关于线性表前面已经说过了,接下来讲具备连续的内存空间、存储相同类型的数据,也正是由于这一点才使数组有了随机访问的特性。blog
咱们拿下面这个例子来进行说明,有一个长度为10的int类型的数组,咱们给它分配一块连续内存空间 1000~1039,内存块的首地址为1000排序
当咱们须要访问其中的数据的时候,计算机会先经过一个寻址公式来找到内存地址,而后再读取其中的数据。队列
在数组中咱们使用的寻址公式为
a[i]_address = base_address + i * data_type_size
base_address为内存块的首地址1000,data_type_size为数据类型的大小,这里咱们使用的是int类型,因此data_type_size为4个字节,也正是这个缘由,在不少语言中,都将数组的第一个下标定为0,由于在寻址的时候,能够直接获得内存地址,而不须要再将数值减一后再进行计算,虽然咱们口算很简单,可是在CPU中,它所进行的运算仍是至关多的。
当咱们须要获得数组中第一个元素的内容时,便直接套公式1000+0*4=1000,便直接获得了内存地址。
因此数组适合查询,支持随机访问,在根据下标进行随机访问时时间复杂度为O(1),这里须要注意一下,说数组的时间复杂度的时候必定要说明在跟进下标进行随机访问的时候,由于若是使用二分查找的话,即使已经进行过排序的数组,时间复杂度也是O(logn)。
可是数组的随机访问的特性有利有弊,由于数组要保证空间是连续的,因此在增长和删除的时候,就须要进行大量的操做将数据进行移动,将是很是低效的。
咱们先来讲插入操做,假如数组的长度为x,那么若是要在第y个位置插入一个数据,那么就须要将y到x的全部数据都日后挪一位,将第y个位置腾出来。
咱们来看一下它所涉及到的时间复杂度,若是插入的数据在最后一个,就不须要进行移动,最好时间复杂度为O(1);若是插入的数据在第一个,则后面的每个数据都须要日后挪一个,最坏时间复杂度为O(n);由于在每个位置插入的几率都是同样的,因此平均时间复杂度为(1+2+…+n)/n=O(n)。
固然这是对数组数据是有序的状况下来讲的,若是数据是无序的话,就不须要这些操做了,若是要在第y位插入数据,只须要将第y位的数据移动到整个数组的最后面,而后再将须要插入的数据插入便可,这个时候的时间复杂度就降为了O(1)。
接下来讲删除操做,与插入数据相似,若是要删除第y位的数据,就须要将y到n的数据都往前挪一个,不然内存空间就不连续了,若是删除数组末尾的数据,最好时间复杂度为 O(1);若是删除开头的数据,最坏时间复杂度为 O(n),删除每个数据的几率是相同的,平均时间复杂度为 O(n)。
数组到这里也就结束了,再接着就是代码实现。
参考文档
极客时间-数据结构和算法之美
文章首发公众号和我的博客:
公众号:无意的梦呓(wuxinmengyi)
这是一个记录红队学习、信安笔记,我的成长的公众号
扫码关注便可
记录红队相关学习笔记