iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >如何解析Java 数据结构中时间复杂度与空间复杂度
  • 664
分享到

如何解析Java 数据结构中时间复杂度与空间复杂度

2023-06-25 12:06:00 664人浏览 安东尼
摘要

这篇文章给大家介绍如何解析Java 数据结构中时间复杂度与空间复杂度,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。算法效率在使用当中,算法效率分为两种,一是时间效率(时间复杂度),二是空间效率(空间复杂度)。时间复杂度

这篇文章给大家介绍如何解析Java 数据结构中时间复杂度与空间复杂度,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

算法效率

在使用当中,算法效率分为两种,一是时间效率(时间复杂度),二是空间效率(空间复杂度)。时间复杂度是指程序运行的速度。空间复杂度是指一个算法所需要的额外的空间。

时间复杂度

什么是时间复杂度

计算程序运行的时间不能拿简单的时间来计算,因为不同处理器处理数据的能力是不一样的。所以只算一个大概的次数就行了,俨然就是算法中的基本操作的执行次数。用大O的渐进法来表示

例:计算 func1 的基本操作执行了几次

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);}

func1 的基本执行次数是:F(N) = N^2 + 2*N + 10

推导大 O 阶的方法

用常数1取代运行时间中的所有加法常数。
2、在修改后的运行次数函数中,只保留最高阶项。
3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶。

所以使用大 O 的渐进法表示之后,func1 的时间复杂度就是:O(N^2)

算法情况

因为当我们用算法计算的时候,会有最好情况和最坏情况和平均情况。我们常说的时间复杂度在 O(N) 这里的时间复杂度就是最坏情况。
最好情况就是最小的运行次数。

举例一:

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

这里的结果是 O(N) 因为根据时间复杂度的计算方法,去除常数,所以 2*N 就是 N 。M 是 10 也可以忽略掉。

举例二:

void func3(int N, int M) {    int count = 0;    for (int k = 0; k < M; k++) {        count++;    }    for (int k = 0; k < N ; k++) {        count++;    }    System.out.println(count);}

这里的时间复杂度是 O(M+N) 因为 M 和 N 的值是未知的,所以是 O(M+N)

举例三:

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

这个的时间复杂度是 O(1) 因为循环里面是常数,所以根据大 O 渐进法,结果就是 O(1)

计算冒泡排序的时间复杂度

public static void bubbleSort(int[] arr){    for (int i = 0; i < arr.length; i++) {        for (int j = 0; j < arr.length - 1 - i; j++) {            if(arr[j] > arr[j+1]){                int tmp = arr[j];                arr[j] = arr[j+1];                arr[j+1] = tmp;            }        }    }}

因为冒泡排序的特殊性,可能一次就排好了,也可能得一直排到最后,所以就有了最好情况和最坏情况。

最好情况:就是比较一次,就是 O(N)
最坏情况:一直排到最后,就是 O(N^2)

计算二分查找的时间复杂度

int binarySearch(int[] array, int value) {    int begin = 0;    int end = array.length - 1;    while (begin <= end) {        int mid = begin + ((end-begin) / 2);        if (array[mid] < value)            begin = mid + 1;        else if (array[mid] > value)            end = mid - 1;        else            return mid;    }    return -1;}

因为二分查找是一半一半的找,所以每次查找之后都会把查找范围减半,比如说在一个 1 - 8 的有序数组里面查找 8 也就是查找最坏情况。图示如下:

如何解析Java 数据结构中时间复杂度与空间复杂度

如图,在数组当中完成二分查找需要 log2n - 1 次也就是时间复杂度是 log2n (就是 log 以 2 为底 n 的对数)

计算阶乘递归的时间复杂度

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

计算递归的时间复杂度:递归的次数 * 每次递归执行的次数。

所以这次递归的时候,基本操作递归了 N 次,所以时间复杂度就是 O(N)

计算斐波那契递归的时间复杂度

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

假设 N 是 5 我们来展开求

如何解析Java 数据结构中时间复杂度与空间复杂度

如图:每次计算都会计算下一层,但是每次都是一边少,一边多。所以就可以直接按照每边一样来计算。如下图:

如何解析Java 数据结构中时间复杂度与空间复杂度

所以就有公式可以计算出每次计算的次数,就是:2 ^ (n - 1) ,所以计算的结果就是:2^\0 + 2^1 + 2^2 + 2^3……2^(n-1) = 2^n+1 所以按照大 O 渐进法来算,结果就是:2^n 。

所以斐波那契数列的时间复杂度就是:2^n 。

空间复杂度

空间复杂度衡量的是一个算法在运行过程当中占用的额外存储空间的大小,因为没必要按照字节来算,而是算变量的个数。也是用大 O 渐进法表示。

计算冒泡排序的空间复杂度

public static void bubbleSort(int[] arr){    for (int i = 0; i < arr.length; i++) {        for (int j = 0; j < arr.length - 1 - i; j++) {            if(arr[j] > arr[j+1]){                int tmp = arr[j];                arr[j] = arr[j+1];                arr[j+1] = tmp;            }        }    }}

因为冒泡排序的变量并没有变化,使用的是额外空间是常数,所以空间复杂度是 O(1) 。

计算斐波那契数列的空间复杂度(非递归)

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;}

因为这里的斐波那契数列开辟了 n 个额外空间,所以空间复杂度为 O(n) 。

计算阶乘递归Factorial的时间复杂度

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

因为是递归,每次递归都会开辟栈帧,每个栈帧占用常数个空间,所以空间复杂度就是 O(N) 。

关于如何解析Java 数据结构中时间复杂度与空间复杂度就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

--结束END--

本文标题: 如何解析Java 数据结构中时间复杂度与空间复杂度

本文链接: https://www.lsjlt.com/news/304953.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • c++中if elseif使用规则
    c++ 中 if-else if 语句的使用规则为:语法:if (条件1) { // 执行代码块 1} else if (条件 2) { // 执行代码块 2}// ...else ...
    99+
    2024-05-14
    c++
  • c++中的继承怎么写
    继承是一种允许类从现有类派生并访问其成员的强大机制。在 c++ 中,继承类型包括:单继承:一个子类从一个基类继承。多继承:一个子类从多个基类继承。层次继承:多个子类从同一个基类继承。多层...
    99+
    2024-05-14
    c++
  • c++中如何使用类和对象掌握目标
    在 c++ 中创建类和对象:使用 class 关键字定义类,包含数据成员和方法。使用对象名称和类名称创建对象。访问权限包括:公有、受保护和私有。数据成员是类的变量,每个对象拥有自己的副本...
    99+
    2024-05-14
    c++
  • c++中优先级是什么意思
    c++ 中的优先级规则:优先级高的操作符先执行,相同优先级的从左到右执行,括号可改变执行顺序。操作符优先级表包含从最高到最低的优先级列表,其中赋值运算符具有最低优先级。通过了解优先级,可...
    99+
    2024-05-14
    c++
  • c++中a+是什么意思
    c++ 中的 a+ 运算符表示自增运算符,用于将变量递增 1 并将结果存储在同一变量中。语法为 a++,用法包括循环和计数器。它可与后置递增运算符 ++a 交换使用,后者在表达式求值后递...
    99+
    2024-05-14
    c++
  • c++中a.b什么意思
    c++kquote>“a.b”表示对象“a”的成员“b”,用于访问对象成员,可用“对象名.成员名”的语法。它还可以用于访问嵌套成员,如“对象名.嵌套成员名.成员名”的语法。 c++...
    99+
    2024-05-14
    c++
  • C++ 并发编程库的优缺点
    c++++ 提供了多种并发编程库,满足不同场景下的需求。线程库 (std::thread) 易于使用但开销大;异步库 (std::async) 可异步执行任务,但 api 复杂;协程库 ...
    99+
    2024-05-14
    c++ 并发编程
  • 如何在 Golang 中备份数据库?
    在 golang 中备份数据库对于保护数据至关重要。可以使用标准库中的 database/sql 包,或第三方包如 github.com/go-sql-driver/mysql。具体步骤...
    99+
    2024-05-14
    golang 数据库备份 mysql git 标准库
  • 如何在 Golang 中优雅地处理错误?
    在 go 中,优雅处理错误包括:使用 error 类型;使用 errors 包函数和类型;自定义错误类型;遵循错误处理模式,包括关闭资源、检查错误、打印错误信息和处理或返回错误。 在 ...
    99+
    2024-05-14
    golang 错误处理
  • 如何构建 Golang RESTful API,并使用中间件进行身份验证?
    本文介绍了如何构建 golang restful api。首先,通过导入必要的库、定义数据模型和创建路由来构建 restful api。其次,使用 go-chi/chigot 和 go-...
    99+
    2024-05-14
    golang git
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作