<数据结构基础学习>(二)简单的时间复杂度分析

一.简单的复杂度分析

O(1) O(n) O(logn) O(logn) O(n^2)

大O描述的是算法的运行事件和输入数据之间的关系

Eg:

数组求和

public static int sum(int[] nums){
        int sum = 0;
        for(int num:nums){
              sum += num;
         }
         return sum;
}

O(n),n为nums中的元素个数。算法和n呈线性关系。

忽略常数,实际时间T=c1*n+c2。

T = 2 *n +2  O(n)

T = 2000*n + 10000 O(n)

T=1*n*n+0 O(n^2)

T=2*n*n+300n+10 O(n^2)

大O为渐进事件复杂度,描述n趋近于无穷的情况

Eg:

1.添加操作 

addLast(e)  O(1)

addFirst(e)    O(n)

add(index, e)    分析方法,严格计算需要概率论计算期望  O(n/2) = O(n)

整体来说,添加操作为O(n)的操作,通常情况下,考虑是最坏的情况 

2.resize O(n)

3.删除操作

removeLast()    O(1)

removeFirst()    O(n)

remove(index, e)    O(n/2) = O(n)

整体来说,删除操作为O(n)的操作

4.修改操作

set(index, e)  O(1)    数组优势:支持随机访问

5.查询操作

get(index)  O(1)

contains(e)   O(n)

find(e)   O(n)

总体来说

增:O(n)  

删:O(n)

改:已知索引O(1);未知索引O(n)

查:已知索引O(1);未知索引O(n)

二.均摊时间复杂度与复杂度的震荡

1.均摊复杂度

假设capacity = n,n+1次addLast,触发resize,总共进行2n+1次基本操作

平均,每次addLast(e)操作,进行2次基本操作

这样均摊计算,均摊时间复杂度是O(1)的。  与当前size无关

removeLast(e)同理

2.复杂度的震荡

同时看addLast和removeLast操作

当capacity = n,此时size = n,addLast(e)与removeLast(e)都会触发resize

addLast  扩容O(n)

removeLast 缩容 O(n)

addLast 扩容O(n)

removeLast 缩容O(n)

......

产生了复杂度的震荡

出现问题原因:removeLast时resize过于着急(Eager)

解决方案:Lazy

remove方法中,当size=capacity/4,才将capacity减半,同时需要保证缩容得到的数组空间data.length/2!=0

        if(size == data.length / 2 && data.length / 2 != 0)
            resize(data.length/2);
原文地址:https://www.cnblogs.com/HarSong13/p/10659934.html