表

抽象数据类型(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)

 

posted on 2019-04-01 10:42  YOOC  阅读(148)  评论(0)    收藏  举报

导航