Java——时间复杂度和空间复杂度

复杂度包括:时间复杂度和空间复杂度,它是用来衡量算法好坏的工具。

时间复杂度:是一个数学函数,定量描述一个算法的运行时间。算法中的基本操作执行次数,为算法的时间复杂度。

时间复杂度是将一个程序中,所有的基本指令执行的次数全部相加得到的一个函数。

例:

//由分析可知,该程序中数据规模n与基本操作次数的关系为:f(n)=3 * N^2 + 9 * N + 32
public static void func1(int N){                //数据规模:N
        //执行1次
        int count = 0;
        //int i = 0执行1次,i<N执行N次,i++执行N次
        for (int i = 0; i < N; i++) {
            //int j = 0执行N次,j<N执行N * N次,j++执行N * N次
            for (int j = 0; j < N; j++) {
                //count++执行N * N次
                count++;
            }
        }
        //int k = 0执行1次,k<2*N执行2 * N次,k++执行2 * N次
        for (int k = 0; k < 2 * N; k++) {
            //count++执行2 * N次
            count++;
        }
        int M = 10;
        //while((M--)> 0)执行10次,(M--)> 0执行10次
        while((M--)>0){
            //count++执行10次
            count++;
        }
        System.out.println(count);
}

 由上例可知,在计算数据规模n与基本操作次数的关系f(n)是需要将每条基本指令执行的次数逐一算出,之后进行相加。

但是在数据规模N足够大时,低次数项和最高次项数的系数对整个函数的影响并不大,所以,在数据结构中我们通常使用大O渐近法来表示时间复杂度。

大O渐近法:计算出数据规模n与基本操作次数的关系f(n)后,只保留最高次项,并且将最高次项的系数看为1,得到O(n)形式的函数。

计算时间复杂度的步骤:

1.确定数据规模n;

2.计算基本指令个数与n的关系;

3.保留最高次项并且将其系数化为1。

简易方法:直接找到执行次数最多的一条语句,对它的执行次数进行化简就得到了该程序的时间按复杂度。

注:有时程序中会出现多个数据规模的情况,这种情况下,需要将每个数据规模与其基本操作次数的关系f(n)计算出来之后进行相加。

时间复杂度一般包括:最好情况、最坏情况和平均情况

但是我们最在意的是最坏情况下的时间复杂度,因为最好情况只是个例,并且只会在极特殊的情况下发生,而平均情况则需要考虑到很多因素,所以通常情况下我们便认为每一种情况发生的概率是相等的,这时平均情况下的时间复杂度也与最坏情况下的时间复杂度相同,所以我们经常提到的时间复杂度都是最坏情况下的时间复杂度。

关于最好最坏时间复杂度,用冒泡排序举例:

public static void bubbleSort(int[] array){
        int n = array.length;
        //外部循环
        for (int i = 0; i < n - 1; i++) {
            //内部循环
            for (int j = 0; j < n - i - 1; j++) {
                if(array[j] > array[j+1]){
                    int tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1]=tmp;
                }
            }
        }
}

最好情况:数组是由小到大的有序数组,只需要进行一次外部循环的比较,就可以得到最终结果。时间复杂度为:O(n)

最坏情况:数组是由大到小的有序数组,每一次都需要进行比较和交换,才能得到最终结果。时间复杂度为:O(n^2)

平均情况:数组是乱序的,但是仍然需要每一次的比较。时间复杂度为:O(n^2)

常见的时间复杂度:

O(1) < O(log(n)) < O(n) < O(n * log(n)) < O(n^2) < O(2^n)(最坏的时间复杂度,一般不会用到这种时间复杂度)

时间复杂度为O(log(n))的举例:

//二分查找
public static int binarySearch(int[] array,int target){
        int left = 0;
        int right = array.length - 1;
        while(right > left){
            int mid = left + (right - left)/2;
            if(target == array[mid]){
                return mid;
            } else if (target < array[mid]) {
                right = mid;
            }else{
                    left = mid + 1;
            }
        }
        return -1;
}

时间复杂度为O(2^n)的举例:

//斐波那契数列的递归算法————时间复杂度O(2^n)
public static int fib(int n){
    return n<2 ? n : fib(n - 1) + fib(n - 2);
}

 如下图所示:递归函数的调用个数是指数型增长,其时间复杂度是O(2^n)

空间复杂度:是对一个算法在运行过程中临时占用存储空间大小的量度。

空间复杂度计算的不是程序占用了多少个字节的空间,而是计算变量的个数,所以其也并没有很大的意义。

空间复杂度的表示也使用大O渐近法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值