【数据结构初阶】第一节.初识时间和空间复杂度

news2024/12/26 0:28:29

文章目录

前言

一、认识数据结构

二、时间复杂度

 2.1 时间复杂度的概念

 2.2 计算时间复杂度

        2.2.1 大O的渐进表示法

2.3 常见时间复杂度计算举例

三、空间复杂度

3.1 空间复杂度的概念

3.2 计算空间复杂度

3.3 常见空间复杂度计算举例

四、常见复杂度的对比; 

总结


前言

今天我们就将进入到数据结构与算法的内容当中,数据结构作为程序员必须掌握的四大件之一,是非常重要的内容,也是一大难点,也是我们必须熟练的掌握的内容;今天就让我们先初步的认识它吧!!!!!!!!!!!!!!!


提示:以下是本篇文章正文内容,下面案例可供参考

、认识数据结构

数据结构全称数据结构与算法;

定义:

数据结构:是一门单独的学科,他和语言没有关系。

数据+结构:用来描述和组织数据的方式。

特点:

数据结构有以下特点:

1、逻辑非常严谨;

2、代码量是非常多的;

3、调试是必不可少的;

注意:

在学习数据结构中,一定要多思考,多画图,多写代码;

二、时间复杂度

2.1 时间复杂度的概念

概念:

算法的时间复杂度是一个数学函数它定量描述了该算法的运行时间;

一个算 法所花费的时间与其中语句的执行次数成正比例;
所以 算法中的基本操作的执行次数,为算法的时间复杂度。

常见的时间复杂度排序:

O(1)< O(log2(n))< O(n)< O(nlog2(n)< O(n^2)< O(n^3)< O(2^n)< O(n!)< O(n^n)

说明:

一般来说,到了O(n^2)及以上数据量大时运行效率极低,所以数据量大时,应选用更有的算法;


 2.2 计算时间复杂度

实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要 大概执行次数,那么这里我们 使用 大O的渐进表示法

2.2.1 大O的渐进表示法

大O符号(Big O notation):是用于描述函数渐进行为的数学符号;

方法的使用规则:

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

 代码举例说明:

代码如下:

计算一下下面代码中func1执行了多少次???

// 请计算一下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);
}

经过分析可知:

执行次数:

 


此时当我们使用大O的渐进表示法以后得到其执行次数:

执行次数:

通过上面我们会发现大O的渐进表示法去掉了那些对结果影响不大的项,简洁明了的表示出了执行次数。  

另外有些算法的时间复杂度存在最好、平均和最坏情况:

最坏情况:任意输入规模的最大运行次数(上界)
平均情况:任意输入规模的期望运行次数;
最好情况:任意输入规模的最小运行次数(下界)
举例说明:
例如:在一个长度为N数组中搜索一个数据x
最好情况:1次找到
最坏情况:N次找到
平均情况:N/2次找到
在实际中一般情况关注的是算法的最坏运行情况,所以数组中搜索数据时间复杂度为O(N)

2.3 常见时间复杂度计算举例

示例1:

// 计算func2的时间复杂度?
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);
}

解析:

第一个for循环执行2N次,while循环执行10次,则F(N) = 2N+10

 

 经过大O的渐进表示法后,为O(N)

示例2:

 代码2:

// 计算func3的时间复杂度?
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);
}

解析:

第一个for循环执行M次;第二个for循环执行N次;

故F(n)=M+N;

经过大O的渐进表示法后,为O(M+N);

示例3:

冒泡排序的时间复杂度

代码3:

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

 解析:

冒泡排序基本操作执行最好N次,最坏执行了(N*(N-1))/2次,通过推导大O阶方法+时间复杂度一般看最坏, 时间复杂度为 :O(N^{2})

示例4:

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

代码4:

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次,最坏O(log(2)N)次,时间复杂度为:O(\log_{2}N)

、空间复杂度

3.1 空间复杂度的概念

概念:

空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度
一个程序的空间复杂度是指运行完一个程序所需内存的大小

3.2 计算空间复杂度

空间复杂度的计算同样要用大O渐进表示法;上面已经介绍过了,此处就不一一赘述了;


3.3 常见空间复杂度计算举例

示例1:

代码1:

public void function() {
    int a[] = { 1, 2, 3, 4, 5 };
    int tmp = 0;
    for (int i = 0; i < (a.length / 2); i++) {
        tmp = a[i];
        a[i] = a[a.length - i - 1];
        a[a.length - i - 1] = tmp;
    }
    System.out.println(Arrays.toString(a));
}

解析:

这是一段很具有迷惑性的代码,虽然看上去有for循环也定义了一个a数组,但是我们再仔细看看代码中都是常量定义的,所以这段代码的空间复杂度实则为O(1).

示例2:

冒泡排序法的空间复杂度

代码2:

//这是一个冒泡排序   
public 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;
            }
        }
    }

解析:
 为了完成这个算法我们在函数中,只开辟了3个变量的内存空间,为常数项,所以冒泡排序法的空间复杂度是O(1).

四、常见复杂度的对比; 


总结

今天的内容就分享到这里了,我们下一节内容再见!!!!!!!!!

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/190099.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CVE-2022-26937 Windows NFS 栈溢出漏洞分析

简介 NFS全称Network File System&#xff0c;即网络文件系统&#xff0c;用于服务器和客户机之间文件访问和共享的通信&#xff0c;从而使客户机远程访问保存在存储设备上的数据。 CVE-2022-26937是微软5月份修复的Windows NFS中一个对NLM响应处理不当的栈溢出漏洞&#xff…

OAuth2(1)

目录 一、什么是OAuth2.0 二、OAuth2中的角色 三、认证流程 四、生活中的OAuth2思维 五、令牌的特点 六、OAuth2授权方式 1.授权码 2.隐藏方式 3.密码方式 4.凭证方式 一、什么是OAuth2.0 OAuth2.0是目前使用非常广泛的授权机制&#xff0c;用户授权第三方应用…

红宝书学习

第一章 认识js js的组成部分有哪些&#xff1f; ①ecma 核心语法 api ②dom 提供与网页内容交互的方法和接口 ③bom 浏览器对象模型&#xff0c;提供了和浏览器交互的接口 use strict 是什么&#xff1f; use strict 是一种 ECMAscript5 添加的&#xff08;严格模式&#xff…

玩了半年NFT,一心进军Web3的Prada到底要怎么玩?

图片来源&#xff1a;无界AI绘画工具生成2022年1月&#xff0c;奢侈品品牌Prada与阿迪达斯玩了一把“联合营销”&#xff0c;玩法是这样的&#xff1a;首先&#xff0c;两个品牌邀请粉丝上传个人照片&#xff0c;然后&#xff0c;品牌抽取3000名粉丝的作品&#xff0c;交由数字…

【Rust】12. 自动化测试

12.1 编写测试 12.1.1 测试函数 测试函数&#xff1a;在一个函数前加上一行 #[test] 注解将普通函数变成测试函数 12.1.2 assert! 宏 12.1.3 assert_eq! 与 assert_ne! assert_eq!(left, right) 与 assert_eq!(left, right) 在失败时会返回 left 与 right 两个值&#xff0c…

Python学习-----起步1

目录 Python的下载&#xff08;解释器&#xff09; IDLE进入Python解释器 交互模式 脚本模式 注释 单行注释&#xff1a; 多行注释 Python的下载&#xff08;解释器&#xff09; 百度网盘链接&#xff1a; https://pan.baidu.com/s/1WEmOAGGHtHc1fxZzNGKu6A?pwd5356 …

web3小白入门:区块链的了解

记录web3学习的过程&#xff0c;从小白开始所有的web3相关的学习内容都会更新在github&#xff0c;github地址这篇文章主要说明区块链的一些概念为什么要了解区块链&#xff1f;Web3 是以区块链技术为核心,构建新一代的去中心化互联网组件,再基于它们来构建我们想要提供的服务、…

HTTP状态码301和302区别

Http 状态码 301 和 302 定义&#xff1a; 1、什么时候使用301&#xff1f; 你将永久更改网页的 URL时。你将永久迁移到新域名时。当你从 HTTP 切换到 HTTPS 时。你希望修复非 www / www 重复内容问题时。永久合并两个或多个页面或网站时。你将永久更改网站的 URL 结构时。 …

万字详解递归与递推

秋名山码民的主页 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f64f;作者水平有限&#xff0c;如发现错误&#xff0c;还请私信或者评论区留言&#xff01; &#x1f44d;目录前言递归斐波那契数列问题的递归爬楼梯问题力扣递归实现…

js 点击图片实现查看大图

js 点击图片实现查看大图 点击图片放大缩小&#xff08;遮罩&#xff09; 截图&#xff1a;点击放大&#xff0c;并显示ico放大镜 代码如下&#xff1a; <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>点击图片放大缩…

buu 浪里淘沙 1

题目描述&#xff1a; 题目分析&#xff1a; 看了这一大串字符串&#xff0c;发现里面都是由16个字母组成&#xff0c;即 “tonight success notice we example crypto should back space sublim found system morning user the enter ”&#xff0c;并且这16个字母在第一行中…

【Kotlin】DSL 领域特定语言 ① ( apply 标准库函数分析 | 普通匿名函数 | 扩展匿名函数 | 泛型扩展匿名函数 )

文章目录一、apply 标准库函数分析1、apply 函数展示2、apply 函数原型分析函数原型参数和返回值分析3、匿名函数类型分析4、扩展函数回顾5、泛型扩展函数函数类型6、泛型扩展匿名函数7、apply 标准库函数参数分析泛型扩展函数匿名函数 与 普通匿名函数 对比apply 函数参数不是…

登高望远,一文解答 2023 年你最关心的前端热点问题

动手点关注干货不迷路本文预计阅读 25 min&#xff0c;建议先收藏后观看~一、刀光剑影的 2022时光荏苒&#xff0c;这绝不平淡的 2022 年已经走上历史的黄页&#xff0c;新的一年也逐渐看不到故人回首的光影。感谢你对前端技术领域持续关注&#xff0c;我们一直在这里等你。① …

致敬2202年,这些优秀的裁缝们

文 | 鹰钩鼻涕虫2202年过去了&#xff0c;不知道小伙伴们是否和我一样&#xff0c;绝大多数时间处于迷茫之中&#xff0c;除去其他因素不谈&#xff0c;在最后一个月到来之前&#xff0c;NLP 学界的表现似乎不如前几年那样“精彩”&#xff0c;甚至可说是“寡淡”&#xff0c;翻…

spring事务执行流程分析_5(注解形式 advisor等前置对象的生成)

调用beanFactory处理器 依旧进入刷新refresh方法AbstractApplicationContext#refresh -> 在上一篇文章spring事务执行流程分析_4(注解形式 EnableTransactionManagement的作用) 解析EnableTransactionManagement注解就是在此方法进行的,也就是在会注册 名字&#xff1a;i…

简单模拟vue实现数据劫持-视图更新双向绑定-2

接上&#xff0c; new一个实例对象&#xff0c;vc&#xff0c;构造函数动态绑定一个空对象&#xff0c;并在构造函数上绑定静态方法 $on进行事件的注册&#xff0c;$emit抛出执行事件 function observe() {// 利用策略模式-可以快速根据特定的事件&#xff0c;执行多个函数th…

最全总结 | 聊聊 Selenium 隐藏浏览器指纹特征的几种方式!

大家好&#xff0c;我是安果&#xff01;我们使用 Selenium 对网页进行爬虫时&#xff0c;如果不做任何处理直接进行爬取&#xff0c;会导致很多特征是暴露的对一些做了反爬的网站&#xff0c;做了特征检测&#xff0c;用来阻止一些恶意爬虫本篇文章将介绍几种常用的隐藏浏览器…

第九层(9):STL之map/multimap

文章目录前情回顾map/multimap概念差别构造函数赋值操作大小操作函数交换函数插入函数删除函数查找函数统计函数排序规则下一座石碑&#x1f389;welcome&#x1f389; ✒️博主介绍&#xff1a;一名大一的智能制造专业学生&#xff0c;在学习C/C的路上会越走越远&#xff0c;后…

三线金叉选股公式,均线、成交量、MACD共振

均线、成交量、MACD三线金叉共振选股公式思路还是比较简单的&#xff0c;分别写出均线金叉、成交量的均量线金叉、MACD的快线和慢线金叉&#xff0c;最后用AND连接这三个条件。 一、编写选股公式所需通达信函数 1、EXIST函数 含义&#xff1a;是否存在 用法&#xff1a;EXIST…

OpenGL | 搭建OpenGL 画画框架

一、搭建OpenGL 画画框架3D场景初始化&#xff08;1&#xff09; 代码void Init() {glMatrixMode(GL_PROJECTION); //将当前矩阵指定为投影矩阵,对投影矩阵操作gluPerspective(50.0f, 800.0f / 600.0f, 0.1f, 1000.0f);//创建一个对称的透视投影矩阵&#xff0c;并且用这个…