一、判断一个算法的好坏,主要从时间复杂度(执行次数)和空间复杂度(占用存储空间)入手
1、时间复杂度
判断算法的执行次数,及观察整个程序一共执行多少次语句,算完后,一般是一个表达式(几元几次),比较复杂不好看,就引用了大O表示法
大O表示法近似于估算的看问题,类似于极限的计算
使用时,会将低阶的项、常数以及系数忽略(这里就是让n趋向于无穷大来看式子的大小)
比如:
(1)9(常数) 用大O表示法后变成O(1)
(2)3n^2+2n+5 使用大O表示法后变成:O(n^2)
(3)nlog2(n) 使用大O表示法后变成:O(nlogn)
从大到小排列:
O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(2^n) < O(n!) < O(n^n)
2、空间复杂度
看占用多少空间,就看定义了多少变量,计算变量占用的空间进行比较
二、数据结构
数据结构是计算机存储、组织数据的方式
主要有线性结构(线性表)、树形结构以及图形结构三种
1、动态数组
java中有动态数组专门的类——Arraylist
以下是自己创建动态数组会使用的知识
泛型
是指在对象建立时不指定类中属性的具体数据类型,而由外部在声明及实例化对象时指定类型
一般是在类名后紧跟<泛型标识>,泛型标识为一个大写字母,本类中函数的形参类型使用泛型时,根据实例要求可以传入不同类型的元素
定义泛型对象格式:
类名<数据类型>对象名 = new 类名<>();
注:<>中数据类型是写包装类,不是基本数据类型,比如int型要写Integer,float型要写Float
对象数组
元素中存放的是地址,而不是对象本身
也就是说,大小是指针的大小,不是数据本身的大小
创建数组时,先在堆空间内使用足够的内存空间放需要大小的元素(不一定和放的元素本身一样大),然后在向数组内添加元素内容时再调用相应内存大小,便于节省内存同时可以确保能够保存不同类型的元素。
对象数组要先开辟一块栈空间,用于开辟存放数组,要对数组进行操作时,依次实例化数组的每一个元素(此过程在堆空间)
画一个不太美观的图来表示:
定义格式:(普通情况下的对象数组)
先声明数组
类名 数组名[] = new 类名[数组长度];
再创建数组元素的对象
类名 元素对象名 = new 类名(想要添加的内容);
数组元素[索引] = 元素对象;
在动态数组中,我们使用Arraylist的add函数添加元素内容
Arraylist<泛型指代的数据类型> 数组 = new Arraylist<>();
数组.add(索引位置,元素内容);
当然,要用到对象数组,即在动态数组中存的不是数值,而是其他数组的对象时, 格式就会有所不同
比如:要存一些人的信息,使用自定义Person类,构造函数包括人名(name)和年龄(age)两个内容,本类中有输出信息的toString()函数
写法就变成:
Arraylist<Person> 数组 = new Arraylist<>();
数组.add(new Person(name,age));
finalize()
为Object类的方法,它相当于GC,用于回收垃圾
当堆空间中的对象没有被栈空间变量指向的时候,这个对象会等待被回收
格式为:
protected void finalize() throws Throwable{}
clear()清空元素
应该使用for循环将元素依次赋为null
而不是直接将数组大小size赋为0,或者直接让数组对象为null
清空数组后,可能以后还需要使用,如果直接将数组对象与连接元素地址的指针断开,数组会被直接销毁,也就是数组占用的地址直接不存在了,没办法再进行其他操作了,这个数组就不能再使用了
如果将size直接赋为0,原数组已有的对象依旧会存在,但是此时对象不会被当做垃圾回收,而是一直占用内存。直到新添加元素,此时新元素会覆盖掉原有的对象,使得第一个地址指向新元素,这时候这个被覆盖掉的元素才会被当做垃圾回收
缩容
与扩容很像,同样是申请一段新的存储空间,只不过缩容新申请的比较小,扩容新申请的比较大
缩容要观察size和容量差多少(这里自己定值),比如如果不到二分之一,就缩容
private void trim(){
int capacity = elements.length; //容量,即数组实际占用的内存
int newCapacity = capacity >> 1; //新容量为原来的二分之一
if (size >= newCapacity || capacity <= DEFAULT_CAPACITY) return;
//如果size比二分之一容量大,或者已经比最小的设定容量小,不需要任何操作
E[] newElements = (E[]) new Object[newCapacity];
for (int i = 0; i < size; i++){
newElements[i] = elements[i]; //将原数组元素转移到新开辟的数组中
}
elements = newElements;
System.out.println(capacity + "缩容为" + newCapacity); //缩容提示信息
}