王道数据结构 第一轮复习笔记

b站视频链接:点击此处

首先先对计算机四大件之间的关系做了一个联系:

开篇——数据结构在学什么?

用程序代码把现实世界的问题 信息化——处理信息从而创造价值。

“唯一可以确定的是,明天会使我们所有人大吃一惊。”
“The sole certainty is that tomorrow will surprise us all.”
                                                                                —— 阿尔文·托夫勒

第一章 绪论

1.1 数据结构的基本概念

1.1.1 什么是数据? 

数据艺术家->用数据描述世界

数据是信息的载体,描述客观事实属性的数。

1.1.2 数据元素、数据项

数据元素是数据的基本单位,通常作为一个整体进行考虑和处理。

一个数据元素可由若干 数据项 组成,数据项是构成数据元素的不可分割的最小单位。举例如下:

 当一个数据项由多个更细分的属性组成,称这样一个数据项为组合项

1.1.3 数据对象

数据对象是 具有 相同性质的数据元素的集合。
数据结构 是 相互之间存在一种或多种特定 关系 的数据元素的集合(线性数据结构——朴实无华排行榜、网状数据结构——人机关系结构)。
数据机构这门课着重关注的是数据元素之间的关系,和对这些数据元素的操作,而不关心具体的数据项内容。
⭐同一个数据对象的数据元素,可以组成不同的数据结构。富豪榜的排行榜(线性)、富豪之间的关系(网状)。
不同的数据元素,可以组成相同的数据结构。eg: 富豪排行榜、微博粉丝排行榜(都是线性数据结构);微博好友关系、朋友圈关系(都是网状数据结构)

1.1.4 数据结构的三要素

逻辑结构
集合结构 —— (408不考)
线性结构 —— 数据元素之间是 一对一的关系。除了第一个元素,所有元素都有唯一的前驱;除了最后一个元素,所有的元素都有唯一的后继。
树形结构 —— 数据元素之间是 一对多的关系。
图形结构 —— 数据元素之间是 多对多的关系

在这里插入图片描述

数据的运算
针对于某种逻辑结构,结合实际需求,定义 基本运算
对于线性结构中,基本运算有 ① 查找第i个数据元素;② 在第i个位置插入新的数据元素;③ 删除第i个位置的数据元素...
物理结构(存储结构)——以线性结构为例
顺序存储:把逻辑上相邻的元素  在物理上 也顺序相邻的存储起来。
链式存储:逻辑上相邻的元素在物理位置上可以 不相邻,借助指示元素存储地址的 指针来表示元素之间的逻辑关系。
索引存储:在存储元素信息的同时,还建立附加的索引表。索引表中的每项称为索引项,索引项的一般形式是(关键字,地址)。(可离散存储)
散列存储(哈希存储):根据元素的关键字直接计算出该元素的存储地址。
若采用顺序存储,则各个数据元素在物理上必须是 连续的;若采用非顺序存储,则各个数据元素在物理上可以是 离散的
数据的存储结构  会影响  存储空间分配的 方便程度
数据的存储结构  会影响  对 数据运算的速度。eg:在b和d之间插入新元素c
运算的定义是针对 逻辑结构的,指出运算的功能;
运算的实现是针对 存储结构的,指出运算的具体操作步骤。
数据类型是一个 值的集合定义在此集合上的一组操作的总称。
数据类型分为 原子类型和结构类型。
1)原子类型:其值不可再分的数据类型。
例:bool类型:值的范围:true、false;可进行的操作:与、或、非。
       int类型 :值的范围:-2147483648 ~ 2147483647;可进行的操作:加、减、乘、除、模运算。
2)结构类型:其值可以再分为若干成分(分量)的数据类型。
struct Coordinate{
        int x;        //横坐标
        int y;        //纵坐标
}
可进行的操作:加、减、计算到原点的距离。(可封装成函数)
补充资料:
原码和补码
原码和补码是两种表示有符号整数的编码方式。
  1. 原码(Sign-Magnitude):

    • 最高位表示符号位,0表示正数,1表示负数。
    • 其余位表示数值部分,直接将数值转换为二进制表示。
    • 例如,+5的原码为 00000101,-5的原码为 10000101。
  2. 反码(One's Complement Representation)

              1. 正数的反码与其原码相同。

              2. 负数的反码是将其原码中除符号位外的每一位取反(0 变为 1,1 变为 0)。

              3. 例如,正数 +5 的反码为 00000101,负数 -5 的反码为 11111010

      3.补码(Two's Complement):

              1. 最高位表示符号位,0表示正数,1表示负数。

              2. 正数的补码与原码相同。

              3. 负数的补码表示方法:其-5原码的反码的基础上+1。

                  eg:-5的补码:5用二进制表示00000101,取反码+1:11111011

              4. 例如,+5的补码为 00000101,-5的补码为 11111011。


补码表示方法的优势在于可以简化负数的运算,使加法和减法可以使用相同的硬件电路来实现。此外,补码还能够表示一个额外的最小值,即最高位为1,其余位为0的情况,这在计算机中常用于表示溢出或错误状态。

需要注意的是,在补码表示中,最小的负数的绝对值无法用原码表示,因为原码中没有对应的正数。例如,在8位补码表示中,最小的负数是-128,其补码为 10000000,而无法用原码表示。

有符号整数

有符号整数是一种表示正数、负数和零的整数类型。它们在计算机编程中广泛使用,用于存储和处理各种数值数据。

有符号整数使用一个比特位(bit)来表示符号,即正号或负号。剩余的比特位用于表示数值的大小。最常见的有符号整数类型是带符号的二进制补码表示法。

在大多数编程语言中,有符号整数类型包括不同的位数,如8位、16位、32位和64位。每个位数的有符号整数类型都有一个范围,可以表示的最小值和最大值取决于位数。

例如,在常见的32位有符号整数类型(int)中,可以表示的最小值是-2,147,483,648,最大值是2,147,483,647。这意味着该类型可以表示从负两亿一千四百七十四万八千三百六十八到正两亿一千四百七十四万八千三百六十七之间的整数。

有符号整数可以进行各种算术运算,如加法、减法、乘法和除法。在进行这些运算时,需要注意溢出的问题,即结果超出了有符号整数类型的表示范围。

1.2. 算法

1.2.1. 算法的基本概念

程序 = 数据结构(存入信息)+算法(处理)

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

算法的特性:有穷性、确定性、可行性、输入、输出。

有穷性:算法必须是有穷的:算法要在有穷步之后结束,且每步都在有穷时间内完成;程序可以是无穷的。

确定性:算法中每条指令必须有确切的含义,相同的输入只能得到相同的输出。

可行性:实现方案可以用计算机代码来实现。

输入:0/多个输入,是取自于某个特定的对象的集合。

输出:1/读个输出,是与输入有着某种特定关系的量。

算法的设计目标:

1)正确性。

2)可读性:帮助别人理解/过段时间自己再看可以理解,写注释。

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

4)高效率与低存储量需求:时间复杂度低,空间复杂度低(时间少、不废内存)
算法和程序十分相似,但又有区别。程序不一定具有有穷性,程序中的指令必须是机器可执行的,而算法中的指令则无此限制。算法代表了对问题的解,而程序则是算法在计算机上的特定的实现。一个算法若用程序设计语言来描述,则它就是一个程序。

1.2.2. 算法的时间复杂度

算法的时间:与机器性能、编程语言、有关编译程序产生的机器指令质量有关。有些算法是不能事后再统计的(导弹控制算法)。

越高级的语言执行效率越低

(越是低级的语言对机器越是友好,越是符合机器的思考方式,因此执行效率高。

    越是高级的语言对人类越是友好,越是符合人类的思考方式,因此开发效率高。)

时间开销T(n) 问题规模n 的关系。(默认每一行代码的执行时间是相同的,实际上肯定不一样)(没有时间单位,因为在不同的机器上执行的速度是不同的。)

#include<iostream>
using namespace std;
void loveyou(int n){
	int i=1;//执行1次 
	while(i<=n){//有穷性  3001
		printf("I Love You %d\n",i);//3000
		i++; //3000
	}	
}
int main(){
	loveyou(3000);
	return 0;
}
//T(3000)=1+3001+2*3000
//T(n)=2+n+2n=3n+2

简化表达式:

T_{1}(n)=3n+3                                     只保留3n就好        \approx O(n)

T_{2}(n)=n^{2}+3n+1000                    只保留n^{2}就好        \approx O(n^{2})

T_{3}(n)=n^{3}+n^{2}+9999999         

= T_{3}(n) = O(n^{3})+O(n^{2})+O(1)  只保留n^{3}就好        \approx O(n^{3})

结论:可以只考虑阶数高的部分。

常用技巧:

a)加法规则:多个大O多项相加,只保留最高阶的项,且系数为1。

T(n)=)T_{1}(n) + T_{2}(n)=O ( f ( n ) ) + O ( g ( n ) ) = O ( m a x ( f ( n ) , g ( n ) ) )
b)乘法规则:多项相乘,都保留

T(n)=)T_{1}(n) * T_{2}(n)=O(f(n))*O(g(n))=O(f(n)*g(n))

举例:

T_{3}(n)=n^{3}+n^{2}log_{2}^{n}=O(n^{3})+O(n^{2}log_{2}^{n})=O(n^{3})

常见的: 很重要 -- 常对幂指阶

O(1)<O(log_{2}^{n})<O(n)<O(nlog_{2}^{n})<O(n^{2})<O(n^{3})<O(2^{n})<O(n!)<O(n^{n})

如何计算:

顺序执行 (不带有循环的代码) 的代码只会影响常数项O(1),可以忽略

② 只需挑 循环 中的一个基本操作分析它的执行次数与n的关系即可。

③ 若有多层嵌套循环,只需关注最深层循环循环了几次,分析循环中的更高阶的部分即可。

找到一个基操(最深层循环)

② 分析该基本操作的执行次数x与问题规模n的关系x=f(n)

③ x的数量级O(x)就是算法时间复杂度T(n)

三种复杂度:

最坏时间复杂度:考虑输入数据“最坏”的情况。
平均时间复杂度:考虑所有输入数据都等概率出现的情况。
最好时间复杂度:考虑输入数据“最好”的情况。
算法的性能问题只有在 n 很大时才会暴露出来。

1.2.3. 算法的空间复杂度

内存空间开销T(n) 问题规模n 的关系

内存中有:

程序代码放入内存中(经过编译之后形成的机器指令)——大小固定,与问题规模无关

数据(局部变量、参数、数组)

无论问题规模怎么变,算法运行所需的内存空间都是固定的常量,算法空间复杂度为:S(n)=O(1)         S代表“Space”

算法原地工作——算法所需内存空间为常量

普通程序:

1、找到所占空间大小与问题规模相关的变量
2、分析所占空间 x 与问题规模 n 的关系 x = f ( n )
3、x 的数量级 O ( x ) 就是算法空间复杂度 S ( n )


递归程序:

1、找到递归调用的深度x问题规模n 的关系 x = f ( n )
2、x的数量级 O(x) 就是算法空间复杂度 S(n)
注:空间复杂度=递归调用的深度(调用的深度n * 每层的数据内存k)或者当每层的数据内存大小不同时,将各级加起来 算 x = f ( n )等等

常用技巧:
a)加法规则:多个大O多项相加,只保留最高阶的项,且系数为1。

T(n)=)T_{1}(n) + T_{2}(n)=O ( f ( n ) ) + O ( g ( n ) ) = O ( m a x ( f ( n ) , g ( n ) ) )
b)乘法规则:多项相乘,都保留

T(n)=)T_{1}(n) * T_{2}(n)=O(f(n))*O(g(n))=O(f(n)*g(n))

常见的: 很重要 -- 常对幂指阶

O(1)<O(log_{2}^{n})<O(n)<O(nlog_{2}^{n})<O(n^{2})<O(n^{3})<O(2^{n})<O(n!)<O(n^{n})

第二章 线性表 ——Linear List

2.1 线性表的定义、基本操作

其实就是三要素

2.1.1定义

线性表是具有 相同数据类型的n(n≥0)个数据元素的 有限序列,其中n为 表长,当n=0时线性表是一个 空表。若用L命名线性表,则其一般表示为 L=(a_{1},a_{2},...,a_{i},a_{i+1}, ... ,a_{n})

 

几个概念:
数据类型:int、struct A等
a_{i} 是线性表中的“第 i 个” 元素线性表中的 位序
a_{1} 是 表头元素a_{n} 是 表尾元素
除第一个元素外,每个元素有且仅有一个 直接前驱 ;除最后一个元素外,每个元素有且仅有 一个 直接后驱

2.1.2 线性表的基本操作

还在不断更新ing~
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值