数据结构(初)(复杂度)

本文深入探讨了数据结构的基础概念,强调其在优化代码效率中的作用。文章详细阐述了算法效率的两个关键指标——时间复杂度和空间复杂度,并通过实例解释了如何使用大O渐进表示法进行计算。举例说明了冒泡排序、斐波那契数列等常见算法的时间和空间复杂度,并解释了如何考虑最好、最坏和平均时间复杂度。此外,还介绍了空间复杂度的计算,包括递归和数组分配空间的情况。

 日升时奋斗,日落时自省

目录

一、首先就是什么数据结构

2、算法效率

3、时间复杂度

3.1时间复杂度的基本概念

3.2大O的渐进表示法

3.3大O的渐进表示方法

3.4添加的使用例

 4、空间复杂度

4.1空间复杂度的概念


一、首先就是什么数据结构

从字面上理解就是   数据+结构 

简单讲:组织数据,计算机储存,所有数据的集合

数据结构的开始我们要了解什么呢,数据结构不就是为了我们能够让我们的代码更快,更节省内存,那如何衡量一个算法的好坏呢

2、算法效率

我们注意的是时间和空间上,时间效率被称为时间复杂度,空间效率被称为空间复杂度

时间复杂度是衡量算法的运行速度,空间复杂度是衡量算法所需的额外空间

3、时间复杂度

3.1时间复杂度的基本概念

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

3.2大O的渐进表示法

void func1(int N){
        int count = 0;
        for (int i = 0; i < N ; i++) {
            for (int j = 0; j < N ; j++) {
                count++;
            }
        }
        for (int k = 0; k < 2 * N ; k++) {
            count++;
        } 
        int M = 10;
        while ((M--) > 0) {
            count++;
        } 
        System.out.println(count);
    }

计算一下当前的代码的时间复杂度

 详细计算下来的次数=N^2+2N+M(温馨提示^这个符号是次幂)

 这里大概执行次数,那么这里我们使用大O的渐进表示法

那当N^2接近无穷大时,数学极限的思想就可以看出2N+M就可以忽略不计了

3.3大O的渐进表示方法

(1)、所有的常数次数都可以替换成1。   O(1)

例如

void func4(int N) {
    int count = 0;
    for (int k = 0; k < 100; k++) {
        count++;
    } 
    System.out.println(count);
}

 该代码执行次数为100次,但是这里时间复杂度千万不能写成O(100)   ,这里就是常数次数了应该写为O(1)

(2)、在修改后的运行次数函数中,只保留最高阶项。

这个就比较好理解了,就是上面提及的代码运行了N^2+2N+M次数,只保留最高阶项,时间复杂度就是O(N^2)


(3)、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶

void bubbleSort(int[] array) {
        for (int end = array.length; end > 0; end--) {
            boolean sorted = true;
            for (int i = 1; i < end; i++) {
                if (array[i - 1] > array[i]) {
                    Swap(array, i - 1, i);
                    sorted = false;
                }
            } if
            (sorted == true) {
                break;
            }
        }
    }

这是我们很常见到的冒泡方法代码块,计算当前的时间复杂度

 

 当先看见就是两个for循环执行的东西,运行次数就是

(n-1)+(n-2)+(n-3)+....+0=n*(n-1)/2

=1/2*(n^2)-1/2

这是精确地计算结果,但是我们需要的是当前的以大O渐进表示去掉当前的常数项,和最高次幂前的常数:时间复杂度是O(N^2)

这里我们多加一点

最坏时间复杂度:拿排序来说,最坏的结果就是每次都行换位置,那O(N^2)

最好时间复杂度:本来就是排好的情况下,时间复杂度为O(N),第一个for循环只跑了一次

平均时间复杂度:将每一种遍历情况加起来除其个数

我们一般说的复杂度都是:最坏时间复杂度

3.4添加的使用例

(1)、

我们来看一下该代码判断,运行多少次?

是一个递归代码

 假设它N=3我们需要的是递推两次,可以推出该代码运行了N-1次

时间复杂度:O(N)

(2)、 

int fibonacci(int N) {
return N < 2 ? N : fibonacci(N-1)+fibonacci(N-2);
}

该代码是斐波那契函数的代码块

 

 当前可以进行向下分很多次,直到最左侧等于1的时候就分完了

时间复杂度也就随着分的次数增加,当前递推了多少次

前三行基本可以看出是2^0、2^1、2^2、2^3

等比数列求和

 运算次数的精确计算=2^N-1

时间复杂度:O(2^N)

 4、空间复杂度

4.1空间复杂度的概念

临时占用存储空间大小的量度

空间复杂度也是通过大O渐进法表示的

用例题来解释空间复杂度如何计算

例题一

void bubbleSort(int[] array) {
        for (int end = array.length; end > 0; end--) {
            boolean sorted = true;
            for (int i = 1; i < end; i++) {
                if (array[i - 1] > array[i]) {
                    Swap(array, i - 1, i);
                    sorted = false;
                }
            } if
            (sorted == true) {
                break;
            }
}

我们还是拿冒泡方法的代码来说空间复杂度

作为形参传进来的数组可不算到空间复杂度里

当前的没有新创建空间所以空间复杂度O(1)

这里解释一下 :sorted为什么不算新创建的空间,因为他只创建了一次,就存在了,系统不会一直创建

例题二

 

 public int[] fibonacci(int n) {
                long[] fibArray = new long[n + 1];
                fibArray[0] = 0;
                fibArray[1] = 1;
                for (int i = 2; i <= n ; i++) {
                    fibArray[i] = fibArray[i - 1] + fibArray [i - 2];
                }
                return fibArray;
            }

该代码是斐波那契非递归的形势

该代码的空间复杂度:O(N)

为什么这里是O(N)因为这个地方

 

 这行代码new了空间,所以所需空间就是N

例题三 

long factorial(int N) {
return N < 2 ? N : factorial(N-1)*N;
}

 刚刚我们求过这个代码的时间复杂度

那空间复杂度呢,这个空间复杂度采用的是压栈

 简单来看就是这样,递归了几次就开辟了多少空间

我们再接触一个特例

int fibonacci(int N) {
return N < 2 ? N : fibonacci(N-1)+fibonacci(N-2);
}

如果是斐波那契的递归方法,空间复杂度又是多少

空间复杂度为O(N)

 前面说到递推几次就可以就会开辟几个空间,这里会先开辟最大次数递归的空间数量,其他的递归都可以存放在该空间下(公用一块能支撑最大递归次数的空间

 

例如斐波那契方法的递归最大次数是最左侧这一条递归链,n-1次

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值