简析时间/空间复杂度

来源:互联网 发布:帝国cms 阿帕奇伪静态 编辑:程序博客网 时间:2024/06/05 13:21

一、 概念的引入
对于一个问题有很多种算法,那么如何衡量哪一种方法最有效呢?一般从两个方面来衡量:一个是时间效率,即算法处理数据时所花费的时间,用时间复杂度来衡量;另一个是空间效率,即算法所需求的存储量的大小,用空间复杂度来表示。
一般认为时间效率更重要
二、时间复杂度
对于解决同一个问题的算法,执行时间短的但当然要比执行时间长的时间效率高,在此我们分析影响算法执行时间的各种因素,从而估算出算法的执行时间。
一般用算法中语句被执行的次数来表示算法的时间复杂度
三、空间复杂度
算法的空间复杂度就是程序运行时所占用的存储空间
一般只统计数据部分所占用的存储空间

下面举例说明:二分查找的非递归实现

int bin_search(int arr[], int key, int left, int right){    while (left <= right)    {        int mid = (left&right)+(left^right)>>1;        if (key > arr[mid])        {            left = mid + 1;        }        if (key < arr[mid])        {            right = mid - 1;        }        else            return mid;    }    return -1;}

二分查找的实现机理如下:
首先确定待查找区间的中间位置mid=(left+right)/2,然后把待查找元素key与中间位置上的元素arr[mid]进行比较,比较的结果有以下三种情况:
(1)key=arr[mid],说明中间位置就是要查找的位置,返回中间位置的下标mid;
(2)key>arr[mid],说明要查找的位置在后半部分,则移动区间的左下标left,使left=(left+right)/2+1,然后在新的区间进行查找;
(3)key< arr[mid],说明要查找的位置在前半部分,则移动区间的右下标right,使right=(lef+right)/2-1,然后在新的区间进行查找;
在这里时间复杂度就是while的循环次数k,而每循环一次就会排除掉目前一半的数字,如果总共有n个数,那我们可以得到这样一个公式 2^k=n 则 k=log2n,所以它的时间复杂度就为0(log2n);空间复杂度为0(1)。

我们再来看一个例子:斐波那契数列的非递归实现

 int Fib(int n){    if (n < 2)        return n;    int pre = 0;    int cur = 1;    int next;    for (int i = 2; i <= n; i++)    {        next = cur + pre;        pre = cur;        cur = next;    }    return next;}

在上述代码中for循环被执行了n-1次,因此该算法的时间复杂度为0(n);空间复杂度为0(1)。
四、递归算法的时/空间复杂度
1、递归算法的时间复杂度为:递归总次数每次递归数*
2、递归算法的空间复杂度为:对象的个数

接下来举例说明:斐波那契数列的递归实现

 int Fib(int n){    if (n < 2)        return n;    return Fib(n - 1) + Fib(n - 2);} int Fib(int n)//简洁版 {     return n < 2 ? n : Fib(n - 1) + Fib(n - 2); }

在上述递归算法中:递归的总次数为2^n次,每次递归的次数为一个常数,因此它的时间复杂度为0(2^n);由于它最多占用n个空间,因此空间复杂度为0(n)。

0 0