表
抽象数据类型(ADT):一组可操作对象的集合
操作类型: add remove contain(包含) union find
1.表的简单数组的实现
虽然数组的容量是有限的,但是我么可以在数组需要扩容的时候创建一个双倍的容量的数组
int [] arr=new int[];
int[] newArr = new int[arr.length * 2];
for(int i=0 ; i<arr.length;i++){
newArr[i] = arr[i];
}
arr = newArr;
上面虽然使用简单的数组实现了表,但是在数据的插入和删除的操作上存在着很大的开销。我们可以分析分析上述表进行插入时的时间复杂度。
在进行插入的操作时最坏的时间复杂度情况会发生在向数组位置0插入数据,在位置0插入数据时会导致数组中所有的数据向后移动一个位置所
该表的最坏时间复杂度为O(N),平均时间复杂度为:O(n+(n-1)+...+1 /n+1)=O(n(n+1)/2(n+1)) =O(n),删除操作的时间复杂度同插入操作一样
我们可以看到,其实开销还是挺大的。
为了解决删除和插入开销大的问题我们需要保证表可以不连续存储,所以就引入了链表
2.链表

可以看上图,一个链表是由多个节点组成的,每个节点中不仅包含表的内容还有一个next链,是一个类似与指针的东西,指向该节点的下一个节点。
时间复杂度:
在进行插入和删除操作时,只需要找到next链指向的节点进行插入和删除所以时间复杂读为O(1)
在进行查询操作时:由于链表在进行查询时都要遍历整个链表所以最坏的时间复杂度为O(n)
3. Arraylist 、LinkedList
从时间复杂度的层面分析LinkedList与ArrayList的区别,当然我们也会根据两个例子代码来说明:
ArrayList 的优点在于在使用get和set方法操作List中现有的成员时,消耗的是常数时间也就是说时间复杂度为O(1),其缺点是在对ArrayList 插入新成员
或删除老成员时消耗时间比较昂贵,时间复杂度为O(n)
LinkedList刚好与ArrayList的性能相反,在进行新成员的插入和老成员的删除操作时时间复杂度为O(1),在进行查询和set操作时的时间复杂度为O(n)
public static void makeList(List<Integer> list,int N){
list.clear;
for(int i;i<N;i++ ){
list.add(i);
}
}
上面代码不管对于LinkedList还是ArrayList makeList的时间复杂度均为O(N)。因为每次调用默认在List的末端进行插入
接下来看下一段代码:
public static void makeList(List<Integer> list,int N){
list.clear;
for(int i;i<N;i++ ){
list.add(0,i);
}
}
在上面例子:
当List为LinkedList时,则这段代码的时间复杂度为O(N)
如果List为ArrayList时,则这段代码的时间复杂度为O(N^2)
原因其实在上面的介绍中已经解答,for循环的时间复杂度为 n 当LinkedList进行插入操作时时间复杂读为 1 所以当list为Linked的时间复杂度为O(n)
但是当list为ArrayList时在进行插入操作的时间复杂度为n 所以 整体时间复杂度为O(n^2)
//这是一段数组求和的代码
public static void makeList(List<Integer> list){
list.clear;
int total=0;
for(int i;i<N;i++ ){
total += list.get(i);
}
}
在调用get方法时 ArrayList的时间复杂度为O(1) LinkedList的时间复杂度为O(n)
所以对于整段代码如果List的为ArrayList则时间复杂度为O(N) 若List为LinkedList则整体上的时间复杂度为O(N^2)
浙公网安备 33010602011771号