今天开始寒假的写写写(记笔记)生活。
本弱渣在经历了期末的洗礼之后开始继续计算机专业课的学习,由于即将参加春招,所以先从最基础最重要的数据结构开始复习。之前刷笔试算法题的时候觉得还算顺手,但是总是觉得有些地方基础不够牢固,所以选择使用王道考研的数据机构来夯实基础,希望能够在面试中能够有更好的表现吧,之后可能还会再把《剑指offer》中的一些不太熟练的题目写到简书上面来。
废话不多说,先是第一章的基本概念1。
数据结构的基本概念
基本概念和术语
- 数据
数据是信息的载体,是描述客观事物属性的数,字符以及所有能输入到计算机中并被计算机程序识别和处理的符号的集合。 - 数据元素
数据元素是数据的基本单位,通常作为一个整体进行考虑和处理。一个数据元素可由若干个数据项组成。数据项是构成数据元素的不可分割的最小单元。例如,学生记录就是一个数据元素,它由学号,姓名,性别等数据项组成。 - 数据对象
数据对象是具有相同性质的数据元素的集合,是数据的一个子集。例如整数数据对象是集合 {0,+-1,+-2…} - 数据类型
数据类型是一个值的集合和定义在此集合上一组操作的总称
- 原子类型: 其值不可再分
- 结构类型: 其值可以再分成若干成分
- 抽象数据类型: 抽象数据组织和与之相关的操作
抽象数据类型(ADT)
ADT是指一个数学模型以及定义在该模型上的一组操作。抽象数据类型的定义仅取决于它的一组逻辑特性,而与其在计算机内部如何实现和表示无关,不论其内部结构如何变化,只要它的数学特性不变,都不影响其外部的使用。通常用(数据对象,数据关系,基本 操作集)这样的三元组来表示抽象数据类型数据结构
在任何问题中,数据元素都不是独立存在的,它们之间存在着某种关系,这种数据元素之间的关系成为结构。数据结构是相互之间存在一种或多种特定关系的数据元素的集合。
数据结构包括三方面的内容,逻辑结构,存储结构,数据的运算。数据逻辑结构和存储结构是密不可分的两个方面。算法的设计取决于选定的逻辑结构,算法的实现依赖于所采用的存储结构。
数据结构的三要素
数据的逻辑结构
逻辑结构是元素之间的逻辑关系,即从逻辑关系上描述数据。它与数据的存储无关,是独立于计算机的。数据的逻辑结构分为线性结构和非线性结构,线性表是典型的线性结构。集合,树,图是典型的非线性结构。
集合:结构中的元素除了同属于一个集合的关系外,没有其他关系
线性结构:结构中的数据之间仅存在一对一的关系
非线性结构:结构中的数据之间存在一对多的关系
图状结构&&网状结构:结构中的元素之间存在多对多的关系
数据的存储结构
存储结构是指数据结构在计算机中的表示,也称物理结构。它包括数据元素的表示和关系的表示。数据的存储结构是逻辑结构用计算机语言的实现,它依赖于计算机语言。数据的存储结构主要有:顺序存储,链式存储,索引存储和散列存储。
顺序存储:把逻辑上相邻的元素存储在物理位置上也相邻的存储单元里,元素之间的关系由存储单元的邻接关系来体现。优点:可以随机存取,每个元素占用最少的存储空间。缺点:只是使用相邻的一整块存储单元,可能产生较多的外部碎片。
链接存储:不要求逻辑上相邻的单元在物理上也相邻。借助指示元素存储地址的指针表示元素之间的逻辑关系。优点:不会出现碎片现象,充分利用所有存储单元。缺点:每个元素因存储指针而占用额外的存储空间,并且只能实现顺序存取。
索引存储:在存储信息的同时,还建立其附加的索引表。索引表的每一项成为索引项,索引项的一般形式是:(关键词,地址)。其优点是检索速度快,缺点是增加了附加的索引表,占用较多的存储空间。在删除和增加数据时要修改索引表,会花费较多的时间。
散列存储:根据元素的关键字直接计算出该元素的存储地址,也称HASH。优点是检索,增加,删除节点的速度都很快。缺点:如果散列函数不好可能会出现元素存储单元的冲突,解决冲突需要增加时间和空间开销。
数据的运算
施加在数据上的运算包括运算的定义和实现。定义针对逻辑结构:指出具体的功能,实现针对存储结构:指出运算的具体步骤。
基本概念1 完!!!
(之前没有系统的复习过这些东西,在有了一定代码量之后看这些概念真有醍醐灌顶之感)
接下来是第一部分的习题的一些知识点提炼
- 在存储数据时,不仅要存储各个数据元素的值,还要存储数据元素之间的关系。
- 链式存储设计时,接点内的存储单元地址一定连续。
- 可以用抽象数据类型去定义一个完整的数据结构。
问答题:
- 对于两种不同的数据结构,逻辑结构和物理结构一定不相同吗?
A:数据的运算也是数据结构的重要方面。比如二叉排序树和二叉树它们的逻辑和物理结构完全相同。两者的运算定义不同。二叉树一般表示层次关系,二叉排序树通常用于排序和查找。 - 试举一例,说明对相同的逻辑结构,同一种运算在不同的存储方式下实现,运算效率不同。
A:线性表可用顺序存储,也可用链式存储。就插入删除而言,顺序存储O(n),链式存储O(1),存取反之。
接下来总结基础知识第二部分
算法和算法评价
算法的基本概念
算法是对特定问题求解步骤的一种描述。它是指令的优先序列,其中每一条指令表示一个或多个操作。
算法具有以下五个特性
- 有穷性:一个算法必须总是(对任何合法的输入值) 在执行有穷步之后结束,且每一步都在有穷的时间内完成。
- 确定性:算法中每一条指令必须有确切的含义,读者理解时不会产生二义性。对于相同的输入只能产生相同的输出。
- 可行性:一个算法是可行的。算法中描述的操作都是可以通过已经实现的基本运算执行有限次实现。
- 输入: 一个算法有零个或多个输入。输入取自于某个特定的对象的集合。
- 输出: 一个算法有多个或一个输出。输出是同输入有着某种特定关系的量。
好的算法应该考虑如下目标
- 正确性
- 可读性
- 健壮性:对输入非法数据,也要能做出适当反应或进行处理。
- 效率于低存储量需求
算法效率的度量
算法效率的度量是通过时间复杂度和空间复杂度来描述的。
时间复杂度
最坏时间复杂度:在最坏情况下的时间复杂度
平均时间复杂度:所有输入实例在等概率出现的情况下,算法的期望运行时间
最好时间复杂度
分析时间复杂度的两条guize
- 加法规则:T(n) = T1(n)+T2(n) = O(f(n)) + O(g(n)) = O(max(f(n), g(n)))
- 乘法规则:T() = T1(n) * T2(n) = O(f(n)) * O(g(n))= O(f(n) * g(n))
常见的渐进时间复杂度有
O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n3)<O(2n)<O(n!)<O(nn)
空间复杂度
定义为该算法所耗费的存储空间,他是问题规模n的函数。渐进空间复杂度也常简称为空间复杂度。
S(n) = O(g(n))
程序中需要一些对数据进行操作的工作单元和存储一些为实现计算所需信息的辅助空间。若输入数据所占空间只取决于问题本身,于算法无关,则只需分析除输入和程序之外的额外空间。
算法原地工作是指算法所需辅助空间是常量,即O(1)
第二部分的知识点罗列完毕,下面是习题中提取的盲点
分析如下代码的执行次数
int m = 0;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= 2 * i; j++) m++;
}
执行次数为n(n+1)
斐波那契数列:递归算法时间复杂度O(2^n)(具体计算略复杂),非递归时间复杂度O(n)
嘛,这就是寒假第一次的笔记了,希望不要烂尾,不要烂尾!!