以斐波那契数列和二分查找为例——探究时间复杂度 和 空间复杂度

算法的复杂度分为时间复杂度和空间复杂度。

  • 时间复杂度

    时间复杂度的理解:

    1. 一个函数,用来计算的是执行基本操作的次数,而非时间。
    2.算法分为最好情况、最坏情况和平均情况,时间复杂度的计量关注的是算法的最坏情况。
    3.一个算法的最坏情况的运行时间是在任意输入下的运行时间的上界,以最坏代表最全。
    4.递归算法的时间复杂度:递归总次数*每次递归次数。
    

    时间复杂度的函数表示:
    T(N)=O(f(N)),称O(f(N))为时间复杂度的O渐进表示法。

    时间复杂度的书写要求:

    1. O(1)不是代表常数次,而是代表一次。
    2. 在有两个未知数时,并且不知m、n大小时,
       则f(n)=O(m+n)——函数分别求值时
         f(n)=O(m*n)——函数循环嵌套时
    3.常数次可忽略
      (2*n)——f(n)=O(n)
    

    代码分析

eg1:

void Test1(int m, int n)// f(n,m) = 2*m*n == O(m*n)
{
    int iCount = 0;
    for (int i = 0; i < 2*m ; ++i)
    {
        for (int j = 0; j < n ; ++j)
        {
        iCount++;
        }
    }
}
// f(n,m) = 2*m*n == O(m*n)

eg2:

void Test2(int n)
{
    int iCount = 0;
    for (int iIdx = 0; iIdx < 10; ++iIdx)
    {
        iCount++;
    }
    for (int iIdx = 0; iIdx < 2*n; ++iIdx)
    {
        iCount++;
    }
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            iCount++;
        }
    }
}
// f(n) =n^2+2*n+10  == O(n)=n^2

eg3:

int factorial(int n)//求n的阶乘,递归法
{
    if(n<=1)
    return 1;
    else
    {
        return n*factorial(n-1);
    }
}

常见的时间复杂度:(七种)
O(1)——常数型
O(n)——线性型
O(n^2)——平方型
O(n^3)——立方型
O(2^n)——指数型
O(log2N)——对数型
O(Nlog2N)——二维型




  • 空间复杂度
    空间复杂度的理解:

    1.算法执行过程中辅助空间的个数,而非所占空间的大小
    2.递归算法的空间复杂度:递归总深度*每次递归所需的辅助空间个数。
    

空间复杂度的书写要求:

1.常数个辅助空间时,都用O(1)表示
2.递归算法中,若是单线程的递归——求递归深度最深的那一次所需要的辅助空间的个数
(单线程——过程不可同时进行;双线程:过程可同时进行。)

代码分析:

eg1:


int Sum(int N)
{
    int count = 0;
    for(int i = 1; i <= N; ++i)
    {   
        count += i;
    }
    return count;
}

空间复杂度:O(n)=1 



实例分析:

1.斐波那契数列
——迭代法

int main()
{
    int n = 5;
    int fib(int n);
    printf("%d", fib(n));//1 1 2 3 5 8 13 21 34
    system("pause");
    return 0;
}   
 int fib(int n)
{
     int a = 1;
     int b = 1;
     int c = 1;
     if(n<2)
     return n;
     while (n > 2)
     {
         c = a + b;
         a = b;
         b = c;
         n--;
     }
    return c;
}
//时间复杂度:O(n)——循环次数为n-1次
//空间复杂度:O(1)——辅助空间个数为常数个

——递归法

int main()
{

    int fib(int n);
    printf("%d", fib(5));//1 1 2 3 5 8 13 21 34
    system("pause");
    return 0;
}   
 int fib(int n)
{
     if (n <= 2)
     {
         return 1;
     }
     else
         return fib(n - 1) + fib(n - 2);
}
//时间复杂度:O(2^n)
//空间复杂度:O(n)

这里写图片描述

2.二分查找
——迭代算法:

int main()
{
        int ret = -1;
        int a[] = { 1,2,3,4,5,6,7,8,9};
        int len = (sizeof(a) / sizeof(a[0]));
        int key = 8;
        int left = 0;
        int right = len - 1;
        int middle = (left + right) / 2;
        int middle = (left + right) >>2;(用移位符替代乘除2int middle = left + ((right - left) >> 2);
        while (left <= right)
        {
            if (key < middle)
            {
                right--;
            }
            else if (key > middle)
            {
                left++;
            }
            else
            {
                return middle;
             }
        }
        printf("%d查找成功", key);
        system("pause");
        return ret;
}
//时间复杂度:O(log2N)——循环次数为log2N次
//空间复杂度:O(1)——辅助空间个数为常数个

——递归算法:

int  binarysearch(int a[], int key, int left, int right)
{
    int ret = -1;
    int middle = left + ((right - left) >> 2);
    while (left <= right)
    {
        if (key < middle)
            return binarysearch(a, key, left, middle - 1);

        else if (key > middle)
            return binarysearch(a, key, middle + 1, right);

        else
            return middle;
    }
     return -1;
}
int main()
{
    int key = 2;
    int binarysearch(int a[], int key, int left, int right);
    int a[] = { 1,2,3,4,5,6 };
    printf("%d 成功",key);
    system("pause");
    return 0;
}

//时间复杂度:O(log2N)——循环次数log2N次
//空间复杂度:O(log2N)——单次所需辅助空间个数常数个。

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值