算法复杂度分析
时间复杂度分析
时间复杂度分析:来评估代码的执行耗时的
大O表示法:不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势
空间复杂度
空间复杂度的全称是渐进空间复杂度,表示算法占用的额外存储空间和数据规模之间的增长关系
数组
数组(Array)是一种用连续的内存空间存储相同数据类型数据的线性数据结构
数组如何获取其他元素的地址值
寻址公式:a[i] = baseAddress + i * dataTypeSize
baseAddrss:数组的首地址
dataTypeSize:代表数组中元素类型的大小,int刑的数组,dataTypeSize=4个字节
为什么数组索引从0开始,而不是1
寻址公式:a[i] = baseAddress + (i-1) * dataTypeSize
此公式对cpu来说就多了一次减法指令,性能不如从0开始
操作数组的时间复杂度
查找
- 随机查询(根据索引查询):数据元素的访问是通过下标来访问的,计算机通过数组的首地址和寻址公式能欧很快速的找到想要访问的元素(O(1))
- 未知索引查询
情况一:查找数组内的元素(O(n))
情况二:查找排序后数组内的元素(O(logn))
插入/删除
数组是一段连续的内存空间,因此为了保证数组的连续性会使得数组的插入和删除的效率变得很低
最好的情况下是O(1),最坏的情况下是O(n),平均情况下的时间复杂度是O(n)
ArrayList
成员变量
构造方法
添加和扩容操作
如果空间够就直接添加,不够的话就扩容后拷贝数组再添加
实现原理
- ArrayList底层是用动态的数组实现的
- ArrayList初始容量为0,当第一次添加数据的时候才会初始化容量为10
- ArrayList在进行扩容的时候时原来容量的1.5倍,每次扩容都需要拷贝数组
- ArrayList在添加数据的时候
- 确保数组已使用长度(size)加1之后足够存下下一个数据
- 计算数组的容量,如果当前数组已使用长度+1后的大于当前数组长度,则调用grow方法扩容(原来的1.5倍)
- 确保新增的数据有地方存储之后,则将新元素添加到位于size的位置上
- 返回添加成功布尔值
如何实现数组和List之间的转换
数组转换成List:Arrays.asList(Array)
,修改原数组会收到影响,因为这个方法没有创建新对象,只是引用了地址
List转换为数组:list.toArray(new String[list.size()])
单向链表
- 链表中的每一个元素称之为节点(Node)
- 物理存储单元上,非连续,非顺序的存储结构
- 单向链表:每个节点包括两个部分:一个是存储数据元素的数据