【数据结构】- 初识数据结构之时间复杂度(上)

news2024/9/25 21:30:35

文章目录

  • 前言
  • 一、什么是数据结构
  • 二、什么是算法
  • 三、算法效率
    • 3.1如何衡量一个算法的好坏
    • 3.2算法复杂度
  • 四、时间复杂度
    • 4.1时间复杂度的概念
    • 4.2大O的渐进表示法
    • 4.3常见时间复杂度计算举例
  • 总结


前言

努力不是为了和别人一较高下 而是为了让生活多一种可能 别让世俗淹没生活的浪漫和热情.
C语言告一段落本章开始我们要学习数据结构,本章是关于数据结构之时间复杂度(上)


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

一、什么是数据结构

数据结构(Data Structure)是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合。

二、什么是算法

算法(Algorithm):就是定义良好的计算过程,他取一个或一组的值为输入,并产生出一个或一组值作为输出。简单来说算法就是一系列的计算步骤,用来将输入数据转化成输出结果。

三、算法效率

3.1如何衡量一个算法的好坏

如何衡量一个算法的好坏呢?比如对于以下斐波那契数列

long long Fib(int N)
{
if(N < 3)
return 1;
return Fib(N-1) + Fib(N-2);
}

3.2算法复杂度

算法在编写成可执行程序后,运行时需要耗费时间资源和空间(内存)资源 。因此衡量一个算法的好坏,一般是从时间和空间两个维度来衡量的,即时间复杂度空间复杂度
时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额外空间。在计算机发展的早期,计算机的存储容量很小。所以对空间复杂度很是在乎。但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度

四、时间复杂度

4.1时间复杂度的概念

时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。一个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知道。但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻烦,所以才有了时间复杂度这个分析方式。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度即:找到某条基本语句与问题规模N之间的数学表达式,就是算出了该算法的时间复杂度
例题一:请计算一下Func1中++count语句总共执行了多少次?

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--)
	{
	++count;
	}
	printf("%d\n", count);
}

Func1 执行的基本操作次数 :

                                   - F(N)=N²+2*N+10
  • N = 10 F(N) = 130
  • N = 100 F(N) = 10210
  • N = 1000 F(N) = 1002010

我们发现N越大,后面项对结果影响越小所以这个时间复杂度是O(N²)

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

4.2大O的渐进表示法

大O符号(Big O notation):是用于描述函数渐进行为的数学符号。
推导大O阶方法:

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

使用大O的渐进表示法以后,Func1的时间复杂度为:

  • N = 10 F(N) = 100
  • N = 100 F(N) = 10000
  • N = 1000 F(N) = 1000000

通过上面我们会发现大O的渐进表示法去掉了那些对结果影响不大的项,简洁明了的表示出了执行次数。
另外有些算法的时间复杂度存在最好、平均和最坏情况:

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

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

例题一:计算Func2的时间复杂度?

void Func2(int N)
{
	int count = 0;
	for (int k = 0; k < 2 * N ; ++ k)
	{
		++count;
	}
	int M = 10;
	while (M--)
	{
		++count;
	}
	printf("%d\n", count);
}

解析:
基本操作执行了2N+10次,通过推导大O阶方法知道,时间复杂度为 O(N)
例题二:计算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;
	}
	printf("%d\n", count);
}

解析:
我们发现这段代码中有M也有N,我们不能说M或者N无限大,N或者M就不重要了,基本操作执行了M+N次,有两个未知数M和N,所以这段代码时间复杂度是O(N+M)
例题三:计算Func4的时间复杂度?

void Func4(int N)
{
	int count = 0;
	for (int k = 0; k < 100; ++ k)
	{
		++count;
	}
	printf("%d\n", count);
}

解析:
我发现代码中虽然有N但是并没有用只用了100,基本操作执行了100次,通过推导大O阶方法,时间复杂度为 O(1);
O(1)不是代表1次,是代表常数次

例题四:计算strchr的时间复杂度?

const char * strchr ( const char * str, int character );
//上述一行代码类似于
while(*str)
{
	if(*str==character)
		return str;
	else
		str++:
}

解析:
strchr() 用于查找字符串中的一个字符,并返回该字符在字符串中第一次出现的位置。
strchr() 其原型定义在头文件 <string.h> 中, char *strchr(const char *str, int c) 在参数 str 所指向的字符串中搜索第一次出现字符 c(一个无符号字符)的位置。
基本操作执行最好1次,最坏N次,时间复杂度一般看最坏,时间复杂度为 O(N)
例题五:计算BubbleSort(冒泡排序)的时间复杂度?

void BubbleSort(int* a, int n)
{
	assert(a);
	for (size_t end = n; end > 0; --end)
	{
		int exchange = 0;
		for (size_t i = 1; i < end; ++i)
		{
			if (a[i-1] > a[i])
			{
				Swap(&a[i-1], &a[i]);
				exchange = 1;
			}
		}
		if (exchange == 0)
		break;
	}
}

解析:
冒泡排序准确来说是一个等差数列,基本操作执行最好N次,最坏执行了(N(N+1)/2)次,通过推导大O阶方法+时间复杂度一般看最坏,时间复杂度为 O(N^2)*
例题六:计算BinarySearch(二分查找 )的时间复杂度?

int BinarySearch(int* a, int n, int x)
{
	assert(a);
	int begin = 0;
	int end = n-1;
	// [begin, end]:begin和end是左闭右闭区间,因此有=号
	while (begin <= end)
	{
		int mid = begin + ((end-begin)>>1);
		if (a[mid] < x)
		begin = mid+1;
		else if (a[mid] > x)
		end = mid-1;
		else
		return mid;
	}
	return -1;
}

解析:
基本操作执行最好1次,最坏O(logN)次,时间复杂度为 O(logN) (logN在算法分析中表示是底数为2,对数为N。有些地方会写成lgN)。(建议通过折纸查找的方式讲解logN是怎么计算出来的);每找一次/2假设找了x次,那么2^x=N ->x=logN(以2为底);但是如果我们采用暴力查找也就是顺序查找需要遍历数组那么时间复杂度就是O(N)
例题七:计算阶乘递归Fac的时间复杂度?

long long Fac(size_t N)
{
	if(0 == N)
	return 1;
	return Fac(N-1)*N;
}

解析:
在这里插入图片描述
通过计算分析发现基本操作递归了N次,时间复杂度为O(N)。
例题八:计算阶乘递归Fac的时间复杂度?

long long Fac(size_t N)
{
	if(0 == N)
	return 1;
	for(size_t i=0; i<N;i++)
	{
		//...
	}
	return Fac(N-1)*N;
}

在这里插入图片描述
解析:
时间复杂度为O(N^2)。
例题九:计算斐波那契递归Fib的时间复杂度?

long long Fib(size_t N)
{
	if(N < 3)
	return 1;
	return Fib(N-1) + Fib(N-2);
}

解析:
计算分析发现基本操作递归了2^ N次,时间复杂度为O(2^N)。
在这里插入图片描述


总结

Ending,今天的时间复杂度的内容就到此结束啦~,如果后续想了解更多,就请关注我吧,一键三连哦 ~

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

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

相关文章

MySQL:基本常识介绍、操作数据库、操作数据库中的表、操作表中的数据(增删改查)、MySQL 函数

文章目录Day 02&#xff1a;一、常见的 SQL 语句二、基本常识1. 数据库的列类型2. 数据库的字段属性三、操作数据库1. 操作数据库2. 操作数据库中的表&#xff08;1&#xff09;创建表&#xff1a;CREAT&#xff08;2&#xff09;修改表&#xff1a;ALTER&#xff08;3&#xf…

肖 sir_就业课__014python讲解

python讲解 一、python梳理 1、python 数据类型有哪些&#xff1f; 字符、列表、元组、字典、集合 2、列表、元组、字典、集合的区别&#xff1f; 3、python中函数&#xff1f; &#xff08;1&#xff09;自定义函数 def 函数名&#xff08;&#xff09; &#xff08;2&#…

聊聊架构方案选择

大家好&#xff0c;我是易安&#xff01; 在完成备选方案设计后&#xff0c;如何挑选最终的方案是一个很大的挑战&#xff0c;因为每个备选方案都是可行的。但是&#xff0c;没有哪个备选方案是完美的&#xff0c;因为每个方案都存在一些缺点或风险。此外&#xff0c;评价备选方…

薅!无魔法无限量GPT-4安卓App安装包;Notion AI从入门到精通;最全大模型进展汇总;雇AI给我打零工 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; 『大模型进展汇总 (持续更新至4月17日)』应该是最全总结了吧 ShowMeAI资料编号 No.T001 &#xff08;进入社群获取高清PDF文件&#x…

AI已经解锁自动化能力 | 颠覆商业模式和劳动力市场

AI已经解锁自动化能力&#xff0c;将颠覆商业模式和劳动力市场。目前AutoGPT的开源项目&#xff1a; BabyAGI、Auto-GPT、AgentGPT、TeenagerAGI、Jarvis。 AutoGPT原理&#xff1a; 3个GPT4协同合作&#xff0c;一个GPT4负责分解目标创建任务&#xff0c;另一个GPT4负责分配…

面试必问的CAS原理你会了吗?

目录 一、什么是CAS&#xff1f; 二、CAS 基本原理 三、CAS 在 Java 语言中的应用 四、CAS 的问题 1、典型 ABA 问题 2、自旋开销问题 3、只能保证单个变量的原子性 五、有态度的总结 在并发编程中我们都知道i操作是非线程安全的&#xff0c;这是因为 i操作不是原子操作…

Jmeter常用断言之XPath断言

一般情况下&#xff0c;使用响应断言和json断言即可满足绝大部分断言需求&#xff0c;Xpath断言主要适用于&#xff1a;返回的数据格式为html或xml。 XPath是W3C的一个标准。XPath是一种表达式语言&#xff0c;它使用路径表达式来选取 XML 文档中的节点或节点集。XPath断言和XP…

Linux中jar包的启动脚本解析及问题

搭建运行环境时&#xff0c;把jar包打好外&#xff0c;我们还需要一个启动脚本&#xff0c;新建一个文件start.sh,内容如下&#xff1a; ps -ef | grep dvmrms | grep -v grep | awk {print $2} | xargs kill -9nohup java -jar dvmrms.jar >/dev/null 2>&1 &sl…

leetcode876.链表的中间节点

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【LeetCode】 目录题目链接解法1&#xff1a;快慢指针解题代码题目链接 题目链接 解法1&#xff1a;快慢指针 解法一&#xff1a;快慢指…

opencv实践项目-修改表格缺失轮廓

目录 1. 背景2. 修复步骤2.1 图像灰度化&#xff0c;并进行高斯模糊2.2 对图像进行阀值处理2.3 查找轮廓2.4 利用存储的值了解表格的位置2.5 提取所有的水平线和垂直线2.6 合并垂直和水平的两个模版 3. 完整代码 1. 背景 如果大家在输入图像时&#xff0c;看到的第二行中的单元…

Laravel使用JWT

开始安装jwt &#xff08;本次安装不建议直接在项目中安装及使用&#xff09; 1.composer 安装jwt composer require tymon/jwt-auth 1.0.0-rc.1 2.在config 文件夹的app.php 中注册服务提供者 providers > [Tymon\JWTAuth\Providers\LaravelServiceProvider::class, ]…

计算机网络考试复习——第一章 1.5 1.6

1.5 计算机网络的类别 1.5.1计算机网络的定义&#xff1a; 系统集合&#xff0c;连接起来&#xff0c;协议工作&#xff0c;资源共享 计算机网络主要是由一些通用的、可编程的硬件互连而成的&#xff0c;而这些硬件并非专门用来实现某一特定目的&#xff08;例如&#xff0…

【Linux问题处理】Aborted (core dumped)报错python

文章目录一、命令检查1.python执行py文件2.gdb执行py文件二、进程检查1.检查所有python程序2.使用gdb检查进程三、core文件检查1.开启core文件存储能力2.core文件存储位置3.gbd查看core文件首先需要在ubuntu系统安装gdb工具。 sudo apt-get install gdbgdb是c的工具&#xff0…

SSM框架整合流程与原理解读(附源码链接)

本文参考黑马教程&#xff0c;对 MyBatis、Spring、SpringMVC 三个框架进行逐步整合&#xff0c;并对整合后事务失效原因进行总结。 源码链接&#xff1a;https://download.csdn.net/download/weixin_43819566/87690821 文章目录 一、搭建整合环境1.1 整合项目说明1.2 整合的思…

通过KNN分类模型预测股票涨跌,然后与基准收益画图对比

目录 1 获取数据 2 特征工程&#xff1a;定义一个用于分类的函数 3 特征工程&#xff1a;生成训练数据 4 根据训练数据对分类模型进行拟合&#xff0c;并给出得分 5 使用训练完成的分类模型进行数据预测 6 定义几个有用的函数 7 生成基准收益和策略收益对比结果 记录一下…

排序算法——快速排序(C语言多种实现及其优化策略)

快速排序总述快速排序递归框架单趟快速排序**hoare法****挖坑法**前后指针法快排改进key的选取**随机选key****三数取中**小区间优化**面对多个重复数据时的乏力**总述 快速排序可以说是排序界的大哥的存在&#xff0c;在c库中的qsort和c库中的sort两个排序底层都是用快速排序…

常用运放电路总结记录

前言 上一篇文章我们复习了一下运放的基本知识&#xff0c;尽量的用简单的描述带大家去理解运算放大器&#xff1a; 带你理解运算放大器 对于运放的使用&#xff0c;存在着一些经典常用的应用电路&#xff0c;这个其实网络上已经有大量的文章做记录总结了&#xff0c;作为电…

【Elastic (ELK) Stack 实战教程】11、使用 ElastAlert 实现 ES 钉钉群日志告警

目录 一、ElastAlert 概述 二、安装 ElastAlert 2.1 安装依赖 2.2 安装 Python 环境 2.3 安装 ElastAlert 2.4 ElastAlert 配置文件 2.5 创建 ElastAlert 索引 2.6 测试告警配置是否正常 三、ElastAlert 集成钉钉 3.1 下载 ElastAlert 钉钉报警插件 3.2 创建钉钉机器…

【硬件外设使用】——can

【硬件外设使用】——can can基本概念can 通讯can使用方法pyb.can can可用的传感器 can基本概念 CAN是Controller Area Network的缩写&#xff0c;即控制器局域网。它是一种多主机串行通信协议&#xff0c;用于连接计算机、传感器、执行器和其他设备。 常用于汽车、工业自动化…

如何在不丢失数据的情况下重装Windows 10?

为什么需要重新安装Windows 10&#xff1f; 随着时间的推移&#xff0c;Windows可能会变慢。这可能是由多种原因引起的&#xff0c;例如您安装了许多额外的启动程序&#xff0c;这些程序会延长启动过程等。如果您的Windows系统速度变慢并且无论您卸载多少程序都没有加速&…