IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【零基础学会数据结构】--时间复杂度与空间复杂度 -> 正文阅读

[数据结构与算法]【零基础学会数据结构】--时间复杂度与空间复杂度

什么是数据结构?

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

什么是算法?

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

算法效率

算法在编写成可执行程序后,运行时需要耗费
时间资源和空间(内存)资源 。因此衡量一个
算法的好坏,一般是从时间和空间两个维度来
衡量的,即时间复杂度和空间复杂度。但是因
为当今科技的发展,计算机的内存容量也在快
速发展,所以我们现在判断一个算法的好坏一
般是看其时间复杂度的大小

时间复杂度

时间复杂度的定义:在计算机科学中,算法的
时间复杂度是一个函数,它定量描述了该算法
的运行时间,但是因为外部因素如编译机器的
不同,不同编译机器下的编译时间也存在差异
因此为了统一,我们不再计算一个算法的运行
时间,而是计算一个算法中基本语句的执行次
数,而一个算法所花费的时间与其中语句的执
行次数成正比例,所以算法中的基本操作的执
行次数,为算法的时间复杂度。

如何计算一个算法的执行时间

一个算法的执行时间大致上等于其所有语句执
行时间的总和,而语句的执行时间则为该语句
重复执行的次数和执行一次所需的时间
举例一
void Func1(int n){
for(i=1;i<=n;i++)    
 //频度为n+1
    for(j=1;j<=n;j++){      
    //频度为n*(n+1)
        c[i][j]=0;              
        //频度为n^2
      for(k=1;k<=n;k++)          	
      //频度为n^2*(n+1)
       c[i][j]=c[i][j]+a[i][k]*b[k][j] 
         //频度为n^3
    }

}


该算法中所有语句频度之和,是矩阵阶数n的函
数,用f(n)表示之。
    所以   f(n)=2n^3+3n^2+2n+1

对于举例一这种比较简单的算法,可以直接计
算出算法中所有语句的频度,但是对于困难的
算法则通常是比较困难的。实际我们在计算时
间复杂度的时候,可以只用算法中的"**基本
语句**"的执行次数来计算算法的工作量"**
基本语句**"指的是算法中重复执行次数和算
法的执行时间成正比的语句(也称为基本操作)
,如循环语句.....同时我们也引进计算时间
复杂度的一个方法:大O渐进法。

大O渐近表示法

O符号(Big O notation):是用于描述
函数渐进行为的数学符号。
推导大O阶法
1、用常数1取代运行时间中的所有加法常数。 
//如果一个算法能计算出准确的一个次数,并
且这个数为常数,那么就用1代替,表示为
O(1)
2、在修改后的运行次数函数中,只保留最高
阶项。
 //如n^2+n^3+3,只取最高阶的,其他舍去,
 表示为O(n^2)
3、如果最高阶项存在且不是1,则去除与这个
项目相乘的常数。得到的结果就是大
O阶。
//如1/2*n,统一将系数变为1,表示为O(n)
使用大O的渐进表示法以后,Func1(举例一)
的时间复杂度为:
    						O(n^3)
N = 10 F(N) = 1000
N = 100 F(N) = 1000000
N = 1000 F(N) = 1000000000
通过上面我们发现大O表示法去掉了那些对结
果影响不大的项,简洁明了的表示了
执行次数
    
另外有些算法的时间复杂度存在最好、平均和
最坏情况:
最坏情况:任意输入规模的最大运行次数(上界)
平均情况:任意输入规模的期望运行次数
最好情况:任意输入规模的最小运行次数(下界)
例如:在一个长度为N数组中搜索一个数据x
最好情况:1次找到
最坏情况:N次找到
平均情况: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--)
	{
		++count;
	}
	printf("%d\n", count);
}

Func2的基本操作次数为2n+10 ,根据大O渐
近法,这个算法的时间复杂度为O(n).
举例三(冒泡排序时间的时间复杂度)
void BubbleSort(int arr[], int len){
   int i, j, temp;
   for (j = 0; j < len - 1; j++){            
       for (i = 0; i < len - 1 - j; i++){    
          if(arr[i] > arr[i + 1]){            
             temp = arr[i];
             arr[i] = arr[i + 1];
             arr[i + 1] = temp;
             }
         }
     }
 }

冒泡排序的时间复杂度应该从思想上进行分析,
最好的情况下只排序一趟也就是n-1.最坏的情
况下整个数组每个数都得进行排序,那么n个
数就得排序(n-1)+(n-2).....+1=n*(n+1)
/2次,时间复杂度就为O(n).
举例四(二分查找算法的时间复杂度)
int BinarySearch(int* a, int n, int x)
{
assert(a);
int begin = 0;
int end = n - 1;
while (begin < end)
{
int mid = begin + ((end - begin) >> 1);
if (a[mid] < x)
begin = mid + 1;
else if (a[mid] > x)
	end = mid;
else
	return mid;
	}
return -1;
}

二分查找算法的时间复杂度也应从思想上进行
分析,假设要查找x次,最好的情况第一次就
找到。那么最坏情况就应该是最后一次找到
或者没找到。根据二分算法,每次的查找以
后都得折半。所以1*2*2*2....(x个2)=数组
长度n,所以x就应该等于log2n
举例五(递归算法的时间复杂度)
long long Fac(size_t N)
{
	if (0 == N)
		return 1;
	return Fac(N - 1) * N;
}


递归算法:递归次数*递归调用的次数
举例五的基本操作执行了n次,所以时间复杂度
为O(n);

空间复杂度

空间复杂度也是一个数学表达式,是对一个算
法在运行过程中临时占用存储空间大小的量度 。
空间复杂度不是程序占用了多少bytes的空间,
因为这个也没太大意义,所以空间
复杂度算的是变量的个数。
空间复杂度计算规则基本跟实践复杂度类似,
也使用大O渐进表示法。
注意:函数运行时所需要的栈空间(**存储
参数,局部变量,一些寄存器信息等**)
在编译期间已经确定好了,此空间复杂度主
要通过**函数在运行**时候显式申请的额外空
间**来确定。
举例六(冒泡排序的空间复杂度)
void vBubbleSort(int arr[], int len){
  int i, j, temp;
    for (j = 0; j < len - 1; j++){            
       for (i = 0; i < len - 1 - j; i++){    
           if(arr[i] > arr[i + 1]){            
              temp = arr[i];
              arr[i] = arr[i + 1];
               arr[i + 1] = temp;
             }
         }
     }
 }


冒泡排序使用了常数个额外空间,所以空间复
杂度为1.
举例八(递归数列的空间复杂度)
long long Fac(size_t N)
{
	if (N == 0)
		return 1;
	return Fac(N - 1) * N;
}
Fac被调用了n次,创建了n个栈帧,每个栈帧
开辟了常数个空间,所以空间复杂度为O(n)
常见复杂度对比

在这里插入图片描述

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-16 19:53:24  更:2021-10-16 19:53:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:31:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码