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 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 408数据结构——绪论&复杂度分析 -> 正文阅读

[数据结构与算法]408数据结构——绪论&复杂度分析

绪论&复杂度分析

考纲内容

    • 数据结构与算法的基本概念
    • 算法复杂度的分析和计算

要求内容

    • 理解数据结构与算法的基本概念
    • 会分析和计算复杂度
  • 思维导图索引
    画布 1.png

1.数据结构概念

  • 数据结构是相互之间存在一种或多种特定关系数据元素的集合。

1.1 数据

  • 数据是信息的载体

1.2 数据元素

  • 数据元素是数据的基本单位
  • 一个数据元素可由若干个数据项组成
  • 数据项是构成数据元素的不可分割的最小单位
    结构关系图如下:数据 > 数据对象 > 数据元素

数据关系图.png

1.3 数据类型

  • 原子类型。其值不可再分的数据类型。如:int
  • 结构类型。其值可以再分解成若干成分的数据类型。如:struct结构体
  • 抽象数据类型。抽象数据组织与之相关的操作

1.4 数据结构

  • 数据结构是相互之间存在一种或多种特定关系数据元素的集合
  • 任何问题中,数据元素都不是孤立存在的,之间存在某种特定的关系,这种数据元素相互之间的关系称为结构
  • 逻辑结构、存储结构、数据的运算

1.5 数据结构三要素

1.5.1 数据的逻辑结构

?从逻辑关系上描述·数据结构,与数据的存储无关
?逻辑结构分为线性结构和非线性结构
?典型的线性结构——线性表
?典型的非线性结构——集合、树、图

分类如下
逻辑结构图.png


  • 集合:同属一个集合,别无其他关系,如图(a)
  • 线性结构:结构中的数据元素只存在一对一关系,如图(b)
  • 树形结构:结构中的数据元素存在一对多关系,如图?
  • 图状或者网状结构:结构中的数据元素存在多对多关系,如图(d)
    4类基本结构关系示例图.png

1.5.2 数据的存储结构

  • 存储结构是数据结构在计算机中的表示(也称映像),又称物理结构。它包括数据元素的表示和关系的表示
  • 数据的存储结构主要有顺序存储、链式存储、索引存储和散列存储

  • 顺序存储

逻辑上相邻的元素存储在物理位置上也相邻的存储单元中,物理位置即信息在计算机中的位置,元素关系由存储单元的邻接关系体现

优点

可以实现随机存储,每个元素占最少的存储空间

缺点

只能使用相邻的一整块存储单元,如果存储连续的几个数据,可能会出现较多的未利用的空间


  • 链式存储

不要求逻辑上相邻的元素在物理位置上也相邻,可以借助指示元素存储地址的指针来表示元素之间的逻辑关系

优点

不会出现碎片现象,能充分利用所有存储单元

缺点

每个元素因为存储指针而占用额外存储空间,没有上一个指针的地址找不到下一个,只能实现顺序存取


  • 索引存储

在存储元素信息的同时,还建立附加的索引表,分别存放数据元素和元素间关系的存储方式,索引表每项称为索引项,索引项的一般形式是(关键字,地址)以后可以联系操作系统的文件系统章节来理解

优点

检索速度快

缺点

附加的索引表额外占用存储空间,增加和删除数据也要修改索引表,花费时间。


  • 散列存储
    根据元素的关键字直接计算出该元素的存储地址,又称哈希存储

优点

检索、增加、删除结点的操作都很快

缺点

若散列函数不好,可能会出现元素存储单元的冲突。而解决冲突会增加时间和空间的开销


1.5.3 数据的运算

包括运算的定义和实现。运算的定义是针对逻辑结构的,指出运算的功能。运算的实现是针对存储结构的,指出运算的具体操作步骤。


2. 算法的基本概念和评价

算法(Algorithm)是对特定问题求解步骤的一种描述,指令的有限序列,其中每一条指令表示一个或多个操作

2.1 算法的五个重要特性


  • 有穷性

有限步骤后结束,每一步都可在有穷时间内完成

  • 确定性

算法中每条指令必须有确切的含义,不存在二义性,即没有歧义

  • 可行性

比如受限于计算机的计算能力,有些算法虽然理论上可行,但实际上无法完成。

  • 输入

一个算法有一个或多个输入

  • 输出

一个算法有一个或多个输出


此外设计一个好的算法应该还要考虑以下4个目标

(1)正确性:算法能够正确的解决求解问题

(2)可读性:算法具有良好的可读性,以便帮助理解

(3)健壮性:输入非法数据时,算法能适当的做出反应或处理,而不会产生莫名奇妙的结果

(4)效率与低存储量需求:效率指的是算法执行的时间,
   存储量需求是指算法执行过程中所需要的最大存储空间,这两者都与问题的规模有关

2.2 算法的时间复杂度

所有语句的频度(执行次数)之和记为 T ( n ) T(n) T(n) ,时间复杂度主要分析 T ( n ) T(n) T(n) 的数量级,通常采用算法中基本运算的频度(执行次数)来分析时间复杂度。因此,算法的时间复杂度记为 T ( n ) = O ( f ( n ) ) T(n) = O(f(n)) T(n)=O(f(n))例如 T ( n ) = n 2 + n + 1 , T ( n ) = O ( n 2 ) T(n)=n^2+n+1,T(n)=O(n^2) T(n)=n2+n+1T(n)=O(n2)
O ( n 2 ) O(n^2) O(n2) 即为所求的复杂度


一般只考虑最坏情况下的时间复杂度,以保证算法的运行时间不会比它更长


  • 加法规则

多项相加,只保留最高阶的项,且系数变为1

T ( n ) = T 1 ( n ) + T 2 ? ( n ) = O ( f ( n ) ) + O ( g ( n ) ) = O ( m a x ( f ( n ) , g ( n ) ) ) T(n)= T_1(n) + T_2~(n) = O(f(n)) + O(g(n)) = O(max(f(n),g(n))) T(n)=T1?(n)+T2??(n)=O(f(n))+O(g(n))=O(max(f(n),g(n)))

  • 乘法规则

多项相乘,都保留

T ( n ) = T 1 × T 2 ? ( n ) = O ( f ( n ) ) × O ( g ( n ) ) = O ( f ( n ) × g ( n ) ) T(n)= T_1×T_2~(n) = O(f(n)) × O(g(n)) = O(f(n)×g(n)) T(n)=T1?×T2??(n)=O(f(n))×O(g(n))=O(f(n)×g(n))

  • Eg:

T 3 ( n ) = n 3 + n 2 l o g 2 n T_3(n) = n^3 + n^2log_2n T3?(n)=n3+n2log2?n

= O ( n 3 ) + O ( n 2 l o g 2 n ) =O(n^3)+ O(n^2log_2n) =O(n3)+O(n2log2?n)
= O ( m a x ( ( n 3 , n 2 l o g 2 n ) ) =O(max((n^3,n^2log_2n)) =O(max((n3,n2log2?n))
= O ( n 3 ) =O(n^3) =O(n3)


  • 常见渐近时间复杂度

O ( 1 ) < O ( l o g 2 n ) < O ( n ) < O ( n l o g 2 n ) < O ( n 2 ) < O ( n 3 ) < O ( 2 n ) < O ( n ! ) < O ( n n ) O(1) < O(log^2n) < O(n) < O(nlog^2n) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n) O(1)<O(log2n)<O(n)<O(nlog2n)<O(n2)<O(n3)<O(2n)<O(n!)<O(nn)
速记方式:常对幂指阶

渐近线如下
大O算法.png

2.2 算法的空间复杂度

  • 算法的空间复杂度 S ( n ) S(n) S(n)定义为该算法所消耗的存储空间,她是问题规模 n n n 的函数,它用来衡量算法随着问题规模增大,算法所需空间的快慢;记为 S ( n ) = O ( g ( n ) ) S(n) = O(g(n)) S(n)=O(g(n))
  • 算法运行过程中使用的辅助空间的大小,所占的空间只取决于问题本身和算法无关,只需要分析除输入和程序之外的额外空间
  • 算法原地工作是指算法所需辅助空间是常量,即 O ( 1 ) O(1) O(1)

王道课程里讲的空间复杂度题目

逐步递增型空间复杂度.jpg
图2.jpg
图3.jpg
图4.jpg
图5.jpg

2.3 复杂度题型总结

2.3.1 循环主体中的变量参与循环条件的判断

此类题应该中出主体语句中与 T ( n ) T(n) T(n) 成正比的循环变量,将之代入条件中计算。例如:

1. int i=1;       2.  int y=5;   
   while(i<=n)        while((y+1)*(y+1)<n)
   		i=i*2;		  y=y+1;

例 1 中, i i i 乘以 2 2 2 的次数正是主体语句的执行次数 t t t ,因此 2 t ? n 2^t\leqslant n 2t?n,取对数后得 t < l o g 2 n t <log_2n t<log2?n,则 T ( n ) = O ( l o g 2 n ) T(n) = O(log_2n) T(n)=O(log2?n)

例 2 中, y y y 1 1 1的次数恰好与 T ( n ) T(n) T(n)成正比,记 t t t 为该程序的执行次数并令 t = y ? 5 t = y - 5 t=y?5,有 y = t + 5 y = t+5 y=t+5, ( t + 5 + 1 ) × ( t + 5 + 1 ) < n (t+5+1)×(t+5+1) < n (t+5+1)×(t+5+1)<n ,得 t < n ? 6 t < \sqrt{n}-6 t<n ??6,即 T ( n ) = O ( n ) T(n) = O(\sqrt n) T(n)=O(n ?)


2.3.2 循环主体中的变量与循环条件无关

此类题可用数学归纳法或者直接累计循环次数。多层循环从内到外分析,忽略单步语句、条件判断语句,只关注主体语句的执行次数。此类问题又可以分为递归程序和非递归程序

  • 递归程序一般使用公式进行递推,例如
【2012统考】求整数 $n(n\geq0)$ 的阶乘算法如下,
其时间复杂度是______

int fact(int n) {
	if( n<=1)	return 1;
	return n*fact(n-1);
}

本题求的是阶乘 n ! n! n! 的递归代码,每次递归调用时 fact () 的参数减一,时间复杂度分析如下: T ( n ) = 1 + T ( n ? 1 ) = 1 + 1 + T ( n ? 2 ) = ? ? ? = n ? 1 + T ( 1 ) T(n) = 1+T(n-1) = 1+1+T(n-2)=???=n-1+T(1) T(n)=1+T(n?1)=1+1+T(n?2)=???=n?1+T(1)递归出口为 fact(1),一共执行n次递归调用 fact() ,故复杂度为 T ( n ) = O ( n ) T(n) = O(n) T(n)=O(n)


  • 非递归程序比较简单,可以直接累计次数,例如
【2017统考真题】下列函数时间复杂度是_____

int func(int n){
	int i=0,sum=0;
	while(sum<n) sum+=++i;
	return i;
}

基本运算 sum+=++i,它等价 ++isum = sum+i每执行一次 i 自增 1i=1 时,sum=0+1;
i=2 时,sum=0+1+2;以此类推得出 s u m = 0 + 1 + 2 + ? ? ? + i = ( 1 + i ) ? i / 2 sum=0+1+2+ ??? +i = (1+i)*i/2 sum=0+1+2+???+i=(1+i)?i/2,可知循环次数满足 t t t 满足 (1+t) * t/2<n,因此时间复杂度为 O ( n 1 / 2 ) O(n^{1/2}) O(n1/2)


2.3.3 运用公式法求时间复杂度例题

void func(int n)
{
	int i,j,x=0;
	for (i=1;i<n;i++)
		for(j=i+1;j<=n;j++)
			x++;
}

思路:

  • 先确定主体语句,主体语句是 x++,复杂度为 O ( 1 ) O(1) O(1)

    • 确定外层循环,因为 i < n i<n i<n,外层循环从 1 1 1 n ? 1 n-1 n?1 ∑ i = 1 n ? 1 \sum_{i=1}^{n-1} i=1n?1?

  • 确定内层循环,因为 j < n j<n j<n,外层循环从 1 1 1 n ? 1 n-1 n?1 ∑ i = 1 n ? 1 \sum_{i=1}^{n-1} i=1n?1?

    • 确定内层循环, j ? n j\leqslant n j?n,内层循环从 i + 1 i+1 i+1 n n n , ∑ j = i + 1 n \sum_{j=i+1}^{n} j=i+1n?
  • ∑ i = 1 n ? 1 ∑ j = i + 1 n 1 \sum_{i=1}^{n-1} \sum_{j=i+1}^{n} 1 i=1n?1?j=i+1n?1

计算过程如下图
复杂度计算.jpg
对于 n ? ( i + 1 ) + 1 n-(i+1)+1 n?(i+1)+1可能有些疑惑,为什么要 + 1 +1 +1,其实就是一个累加计数的过程,下面给出解释
解释.jpg
0 0 0 的位置到 100 100 100 的位置总共有 101 101 101 个位置,每个位置自增 + 1 +1 +1,也就是 101 101 101 1 1 1相加。


3. 思维拓展

求解斐波那契数列

F ( n ) = { 1 , n = 0 , 1 F ( n ? 1 ) + F ( n ? 2 ) , n > 1 F(n) = \left\{\begin{matrix}1,\quad\quad\quad\quad\quad\quad\quad n=0,1&&&\\F(n-1)+F(n-2),n>1 \end{matrix}\right. F(n)={1n=0,1F(n?1)+F(n?2)n>1?

有两种算法:递归算法非递归算法,试分别分析两种算法时间复杂度。


3.1递归算法

首先写出递归算法的函数

int fact(int n)
{
	if(n==0||n==1)	
		return 1;
	else
		return(fact(n-1)+fact(n-2))
}

先给出我的想法
斐波那契数列时间复杂度.jpg

  • n ? 1 n\leqslant1 n?1 的时候,就直接return了,时间复杂度为 O ( 1 ) O(1) O(1)

  • n > 1 n>1 n>1 的时候,调用递归函数入口fact(n-1)fact(n-2),然后还要进行判断,

    • 时间复杂度为 O ( 1 ) + T ( n ? 1 ) + T ( n ? 2 ) O(1)+T(n-1)+T(n-2) O(1)+T(n?1)+T(n?2)
  • 接着继续进入函数调用入口,直到 T ( 1 ) T(1) T(1) ,得出 2 n ? 1 O ( 1 ) 2^{n-1}O(1) 2n?1O(1),由大O算法的数量级知,时间复杂度为 O ( 2 n ) O(2^{n}) O(2n)


3.2 非递归算法

非递归函数代码如下

int Fibonacci(unsigned int n)
{
	int a = 1, b = 1, c = 0;//a保存f(n-2),b保存f(n-1),c保存f(n)
	for(int i = 3; i <= n; i++)//递推求出f(i)
	{
		c = a + b;//f(n) = f(n - 1) + f(n - 2)
		a = b;//a保存b
		b = c;//b保存c
	}
	return c;
}

可以看出时间复杂度为 O ( n ) O(n) O(n)

3.2 递归算法的优点和缺点

递归优点:
1. 简洁
2. 容易理解思路清晰
3. 可以解决非线性的执行过程。
缺点:
1.递归由于是函数调用自身,而函数调用是有时间和空间的消耗的:
每一次函数调用,都需要在内存栈中分配空间以保存参数、返回地址以及临时变量,
而往栈中压入数据和弹出数据都需要时间

2.递归中很多计算都是重复的,由于其本质是把一个问题分解成两个或者多个小问题,
多个小问题存在相互重叠的部分,则存在重复计算,如fibonacci斐波那契数列的递归实现

3.调用栈可能会溢出,其实每一次函数调用会在内存栈中分配空间,
而每个进程的栈的容量是有限的,当调用的层次太多时,就会超出栈的容量,从而导致栈溢出

总结:
耗费内存、速度慢

建议:
能用循环解决的问题不要使用递归。

4.归纳一个在天勤数据结构看到的递归时间复杂度总结

递归方程.png
本章节结束

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-22 14:55:44  更:2021-09-22 14:56:01 
 
开发: 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 2:37:16-

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