浅谈时间复杂度和空间复杂度

时间复杂度

定义:

一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。

注意:不是指程序运行时间

计算方法:

在计算时间复杂度的时候,先找出算法的基本操作,然后根据相应的各语句确定它的执行次数,再找出 T(n) 的同数量级(它的同数量级有以下:1,log2n,n,n log2n ,n的平方,n的三次方,2的n次方,n!),找出后,f(n) = 该数量级,若 T(n)/f(n) 求极限可得到一常数c,则时间复杂度T(n) = O(f(n)) 。

空间复杂度

定义:

空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度,记做S(n)=O(f(n))。比如直接插入排序的时间复杂度是O(n^2),空间复杂度是O(1) 。而一般的递归算法就要有O(n)的空间复杂度了,因为每次递归都要存储返回信息。一个算法的优劣主要从算法的执行时间和所需要占用的存储空间两个方面衡量。

注意:不是计算空间,而是指对象的个数

计算方法:

空间复杂度计算规则:
1、个数为常数用O(1)表示
2、递归空间复杂度:递归的次数*每次递归所需要的辅助空间 空间复杂度一般用大O渐进法来表示

代码举例说明:

1、折半查找法–非递归法

int BinarySearch(int *arr, int len, int k)

{
    int left = 0;
    int right = len;
    int mid = 0;
    while (right >= left)
    {
        mid = left + ((right - left) >> 1);
        if (k>arr[mid])
        {
            left = mid + 1;
        }
        else if (k<arr[mid])
        {
            right = mid - 1;
        }
        else
            return mid;
    }
    return -1;

}

int main()

{
    int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    int len = sizeof(arr) / sizeof(arr[0]) - 1; 
    printf("%d\n", BinarySearch(arr, len, 7));  
    return 0;
}

代码分析:

当数组的长度为N时:
第一次查找:N/2;
第二次查找:(N/2)/2 = N/(2^2);
第三次查找:((N/2)/2)/2 = N/(2^3);
第k次查找:(N/2)/(2^k)
所以:数学表达式为:k = log(2^N);
而程序只调用一次,每次调用所需的空间为3,所以空间复杂度为常数

结果:

时间复杂度为O(n)=log(2^n)*常数=log(2^n);
空间复杂度为O(1),函数中创建的对象为常数项;

2、折半查找法–递归法

int BinarySearch(int *arr, int left, int right, int k)
{
    int mid = left + ((right - left) >> 1);
    while (left <= right)
    {
        if (arr[mid] == k)
        {
            return mid;
        }
        else if (arr[mid]>k)
        {
            return BinarySearch(arr, left, mid - 1, k);
        }
        else if (arr[mid]<k)
        {
            return BinarySearch(arr, mid + 1, right, k);
        }
    }
    return -1;
}
int main()
{
    int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int left = 0;
    int right = sizeof(arr) / sizeof(arr[0])-1;
    printf("%d\n", BinarySearch(arr, left, right, 7));
    return 0;
}

代码分析:

当数组的长度为N时:
第一次查找:N/2;
第二次查找:(N/2)/2 = N/(2^2);
第三次查找:((N/2)/2)/2 = N/(2^3);
第k次查找:(N/2)/(2^k)
所以:数学表达式为:k = log(2^N);
而程序只调用log(2^N)次,每次调用所需的空间为1,所以空间复杂度log(2^N)*1;

结果:

时间复杂度:O(n)=log(2^n)*常数=log(2^n);
空间复杂度为O(n)=log(2^n)*常数=log(2^n);

猜你喜欢

转载自blog.csdn.net/zl_8577/article/details/78764082