二、数组

教材《数据结构与算法第二版

关键字【连续空间、长度不变】

数组是内存空间的一个连续空间,你肯定见过内存条,你可以想象你的数组存放在内存条的某一段上,特点是连续空间通过下标(index)去管理位置。

例如,下面表示,声明了一个数组,长度为50,里面的元素类型是 int 类型。而且,需要注意,数组的声明当然还有其他声明方式,但不是这里的学习重点。

int[] ints = new int[50]

数据结构-数组的特点是一串连续的空间,例如,上面的数组表示,快递上门派件,街道旁边有一排房子,分别是0-49号(对,因为数组下标是从0开始的),要找到其中的某个主人Bob可能很慢,需要挨家挨户核对主人名字才行。所以派件都会直接核对门牌号,达到最快地投放快件,因为门牌号和下标一样,是这条街道上区分房子的最显著标志。这就是连续空间的好处。如果看到49号后面没有了,我们就不会再找下去了(事实上也找不下去了,因为街道已经没了,这个街道的最大长度就是50)。 

大O表示法(时间复杂度),忽略机器性能,忽略编译执行的效率,只关注 数据量对时间复杂度的影响。比如,快递员派件,走到1号和走到49号房子,走到任何一个房子的时间复杂度是一致的,都是1,派两家的件的时间复杂度为2。给每家都派件(遍历)的时间复杂度是O(N),N表示了有多少家房子。


 插入:

无序数组的插入是最快的,直接在数组的末尾插入元素就可以了。新元素插入在头部的无序数组数组很少,也不会有人去这么干,为什么呢,接着看下去就知道了。使用大O表示法为 O(1) ,简单粗暴,找到最后一个元素的屁股,强势插入!

有序数组就没这么简单了,要求插入之前,先要找到新元素逻辑上应该在的位置,比如有一串数组,长度为26,下标是[0-25],里面预先存放了['a','b','d',_,_,_......] 类型是char,方便编辑,char直接使用字母,不用单引号表示。这个数组已经存放了3个元素了,我要插入新元素c ,因为有序数组的条件,我必须按照英文字母排序方式去放置c,把c和数组里已有的有序内容进行比较,就知道c应该在b和d之间(这个比较的过程,计算机会把c和每个元素比较,比前一个大,比后一个小,就是c的位置了。),好了,可以直接插入吗,肯定是不可以的。数组需要把后面的元素妥善安置一下,所以,d被向后移动一个下标,到它的新家-下标为3的内存区域,d原来的位置-下标2的内存区域就放置了c。这样:[a,b,c,d,_,_...]就完成了有序数组的插入。

关键点来了:有序数组的插入会经过 :-比较——移动——插入-,三个步骤完成。上面的例子只是移动了一个d,如果d后面还有f-z这么多元素的,那就表示右面的所有元素都要移动,这个操作就导致了有序数组的插入效率是很差的,因为“移坑”。

删除:

删除——无论是有序数组,还是无序数组,非末尾的删除,都会导致中间某个index里面的元素不存在,那么后面的元素也需要逐个向前移动,填补这个位置,我称之为“填坑”。我曾经问我自己,就不能空着吗?然后我给了自己一耳光。

遍历:

无论是有序数组还是无序数组,遍历都非常快,因为数组的连续空间,遍历只需要按照下标,挨家挨户敲门就可以了。

总结:

数组是存放数据常见的格式。数组更多适用于读取,无序数组的插入是最快的。有序数组的插入,无序/有序的删除都涉及到后续数据的填坑,所以插入删除效率不高。

下一章是关于数组的排序方法。

课外题:

如果声明了数组后,下标没有放置元素进入,这些下标里有什么呢null,空,0?如果你不确定,动手复制main函数运行一下就知道了。结合java数据类型的初始化,相信这是很简单的。

 public static void main (String[] args){
        int[] ints = new int[5];
        System.out.println("int数组初始化后,元素为:" + ints[4]);
        char[] ars = new char[26];
        System.out.println("char数组初始化后,元素为:"+ars[4]+"....");
        String[] strs = new String[5];
        System.out.println("String数组初始化后,元素为:"+strs[4]);
        boolean[] boos = new boolean[5];
        System.out.println("String数组初始化后,元素为:"+boos[4]);
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值