时间、空间复杂度

引入原因

  • 复杂度是衡量算法性能的重要指标之一,程序员在设计代码时应该从时间和空间两个角度去考虑代码的结构。虽然在计算机硬件在日新月异的提高性能,但在某些情况下,如在高负载或者数据规模很大时,时间和空间复杂度会成为算法性能的瓶颈。
  • 从程序员自我进阶角度,编码不仅限于实现业务逻辑,而要去追求在尽可能少的资源下,完成功能的执行。以这个标准去要求自己,才可能成为一名优秀的程序员。

时间复杂度

1.分类

  • 最坏时间复杂度:程序执行最坏情况下的耗时,执行时间最长。
  • 最好时间复杂度:程序执行最好情况下的耗时,执行时间最短。
  • 平均时间复杂度:累计所有情况下执行耗时,取平均值。
  • 均摊时间复杂度:加权平均执行时间。

2. 表示方法

    T(n)=O(f(n))

    T(n) : 代码执行时间   f(n) : 每行代码执行次数的总和

3.分析方法

  • 只关注循环执行次数最多的一段代码
  • 加法法则:总复杂度等于量级最大的那段代码的复杂度

    T(n)=T1(n)+T2(n)=max(O(f(n)),O(g(n)))=O(max(f(n),g(n)))

  • 乘法法则:嵌套代码的复杂度等于嵌套内外代码复杂度的乘积

    T(n)=T1(n)*T2(n)=O(f(n))*O(g(n))=O(f(n)*g(n))

4.计算时间复杂度

// 简单冒泡排序(升序实现)
void BubbleSort(int *parr, int length)
{
    for (int i = 0; i < length; i++)
    {
        for (int j = i+1; j < length; j++)
        {
            if (parr[j] < parr[i]){ swap(parr[j], parr[i]);}   // swap(i,j)交换数值
        }
    }
}

上述代码是简单冒泡排序的一种实现,分析该段代码的时间复杂度,对于两层for循环,显然应该用乘法法则。

时间复杂度:\frac{1}{2}*(n-1)*n=O(n^{2})

// 优化冒泡排序(升序实现)
void BubbleSort(int *parr, int length)
{
    for (int i = 0; i < length; i++)
    {
        bool flag=false;
        for (int j = i+1; j < length; j++)
        {
            if (parr[j] < parr[i]){ swap(parr[j], parr[i]); flag=true; } //swap(i,j)交换数值
        }
        if(flag=false) return;
    }
}

上述是改进版的冒泡排序实现,当第二个for循环遍历执行一次后,如果标记为假,则表示排序完成。因此在待排序已经是升序排列时,此时,有最好的时间复杂度:O(n)

空间复杂度

void print(int n){
    int i=0;
    int[] parr=new int[n]; // 申请大小为n的int类型数组
    for(int i=0;i=0;--i){
        cout<

上述代码中,申请了大小为n的int类型数组,除此之外,剩余的代码没有占用更多的空间,即和数据规模无关,因此整段代码的空间复杂度为O(n)。

常见的空间复杂度有O(1)、O(n)、O(n*n),O(logn)、O(n*logn)这样的空间复杂度不太常见。

你可能感兴趣的:(算法,时间/空间复杂度)