第二章 一些基本概念

1.数据

数据元素是一个基本的数据单位,通常是一个小整体,一个数据元素可以由多个数据项组成,数据项是构成数据元素不可分割的最小单位。多个性质相同的数据元素可以组成一个数据对象
比如,小明同学的信息包括了学号,姓名,班级三个,那这三个就是数据项,小明同学作为一个数据元素包含这三个数据项。多个同学加上老师可以构成一个班级管理系统,这就是一个数据对象。

数据结构则是用于处理数据元素之间关系的工具
比如我们要找到学生的信息,那么学生都有特定的联系,这时候就可以用数据结构来遍历,除去老师,因为老师虽然和学生在同一个数据对象中,但是关系并不一致。
同一个数据对象里面,可以存在着多种数据结构,来表示不同的关系

2.数据结构的四大逻辑结构

2.1 集合结构

各个数据元素在同一个集合里面。比如一个班的花名册,排名不分先后。

2.2 线性结构

每一个元素之间呈现一个一对一的线性的关系,有前驱后继。比如班级排名。

2.3 树形结构

每一个元素和多个数据元素之间有关系,一对多。比如一个班级对应多个班级职位,而一个班级职位又对应了多个学生。

2.4 网状结构

多个元素对应多个元素,多对多。比如一个班里面,每一个同学都会有多个好友。

3.对数据的运算

就是对数据的操作方法,简单介绍一下线性结构的运算:
1.查找第i个数据元素。
2.在第i个位置插入元素。
3.删除第i个位置的元素。

4.实现数据结构

前面说的是定义,它不同于实现,要实现有多种方法。存储方式,一共有四种,分别是顺序存储,链式存储,索引存储和散列存储(哈希存储)。后面章节都会细谈。

不同的实现方法都会有自己的优点和缺点(会影响运算的速度和存储的方便程度),需要根据实际的需求去衡量。

定义加实现,就可以完成一个数据结构。

5.数据类型和抽象数据类型

5.1数据类型

数据类型分为原子类型和结构类型原子类型不可再分,比如bool类型,int类型。结构类型是可以分解的,比如一个strcut结构体。

5.2 抽象数据类型(ADT)

ADT其实就是数据结构,因为如果你把多个数据元素的关系集合看作一个整体,我们可以称它为一种类型,比如一个班级可以作为一个类型。

6.算法

程序 = 数据结构 + 算法
算法就是对数据的操作方法。

6.1 算法的五大特性

1.有穷性

它要可以运行完。

2.确定性

对于相同的输入,只能得到相同的输出。

3.可行性

必须可以用代码实现。

4、5.输入和输出

算法可以没有输入,也可以有一个或者多个输入,但是必须有一个或多个输出。算法和函数非常相似。

6.2 好算法的特征

1.正确性

能对正常的输入给出正确输出。

2.有可读性

不管是伪代码,还是C语言,至少要自己看得懂。

3.健壮性

可以处理非法数据。

4.时空复杂度低

7.时空复杂度的计算

7.1 时间复杂度的计算

直接用电脑运行则和机器性能相关,和编程语言相关所以,只靠运行则会导致测不准。

1.时间复杂度的计算

于是我们把算法的时间开销称为T,解决问题的规模称为n,所以就是找T关于n的函数T(n)。那么我们就可以用算法中执行代码的行数的数量来和n的关系来表示时间复杂度。比如下面这样的代码:

Test(int n){
1.int i = 0;
2.while(i<n){
3.i++;
4.cout<<"hello"<<endl;}
}

在这段代码中,1会运行1次,2的判断会运行n+1次(因为最后要多一次判断),3和4均会运行n次,故T(n)=3n+2。

2.时间复杂度的简化表示

当T(n)= 3 n 3 + n 2 3n^3 + n^2 3n3+n2的时候,我们可以用等价无穷大的思想,把表达简化,我们仅表示其等价无穷大,用O(n)表示,所以我们可以写成O(n)= n 3 n^3 n3

3.时间复杂度的运算

加法规制 T ( n 1 ) + T ( n 2 ) = m a x ( O ( f ( n ) ) , O ( g ( n ) ) ) T(n_1)+T(n_2)=max(O(f(n)),O(g(n))) T(n1)+T(n2)=max(O(f(n)),O(g(n)))(多项式相加,直接选最大的)
乘法规则: T ( n 1 ) × T ( n 2 ) = O ( f ( n ) × O ( g ( n ) ) ) T(n_1)\times T(n_2)=O(f(n)\times O(g(n))) T(n1)×T(n2)=O(f(n)×O(g(n)))(多项式乘法,留下最大的)

4.时间复杂度排行

非常重要,背这里就行
注意,算法的log没有特殊说明,都是以2为底的。
O ( 1 ) < O ( l o g n ) < O ( n ) < O ( n l o g n ) < O ( n 2 ) < O ( n 3 ) < O ( 2 n ) < O ( n ! ) < O ( n n ) O(1)<O(logn)<O(n)<O(nlogn)<O(n^2)<O(n^3)<O(2^n)<O(n!)<O(n^n) O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n3)<O(2n)<O(n!)<O(nn)
记住公式:常对幂指阶
实在不行就做一个除法,比较两个在n趋近于无穷的时候的极限 l i m n − > ∞ f ( n ) g ( n ) lim_{n->∞} \frac{f(n)}{g(n)} limn>g(n)f(n),用洛必达洛就行。

5.计算时间复杂度

因为顺序执行的部分都是常数,所以我们在计算代码的时间复杂度的时候,我们只需要计算一下循环里面的执行次数就行,比如一层循环是O(n),两层嵌套是O( n 2 n^2 n2),面对多层循环嵌套时,我们选择最内层的去算即可
对于输入的不同,有时候时间复杂度不是一定的,我们主要按照最坏的情况或者平均情况去算,所以只需要算平均和最坏情况即可。

6.空间复杂度计算

6.1 程序运行时需要的内存

(1)需要把整个程序都导入内存中,所以需要固定存放所有代码的数据,但是这个往往不需要考虑。
(2)运行时所需要和产生的局部变量以及参数,计算空间复杂度所计算的就是这部分的内容。

空间复杂度一样用英文的首字母表示为S(n)。如果空间复杂度为常数(S(n)=O(1))则可以称为该算法能够原地工作

6.2 空间复杂度的计算

和时间复杂度一样,如果代码的参数不存在变量时,它就是常数级别。如果存在变量,则只需要注意运行时,变量的数目大小即可,并且往往取其同阶的最小无穷大级数O即可。循环分析一轮即可,但是递归需要考虑每一轮。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值