mirror of
https://github.com/142vip/408CSFamily.git
synced 2026-04-13 18:00:58 +08:00
feat: 新增操作系统、数据结构笔记文档
This commit is contained in:
@@ -1,6 +1,32 @@
|
||||
export const cppSidebar = [
|
||||
{
|
||||
text: '计算机组成原理',
|
||||
text: '引论',
|
||||
prefix: 'basic-introduction',
|
||||
children: []
|
||||
},
|
||||
{
|
||||
text: '数据的表示和运算',
|
||||
prefix: 'basic-introduction',
|
||||
children: []
|
||||
},
|
||||
{
|
||||
text: '存储系统',
|
||||
prefix: 'basic-introduction',
|
||||
children: []
|
||||
},
|
||||
{
|
||||
text: '中央处理器',
|
||||
prefix: 'basic-introduction',
|
||||
children: []
|
||||
},
|
||||
{
|
||||
text: '总线',
|
||||
prefix: 'basic-introduction',
|
||||
children: []
|
||||
},
|
||||
{
|
||||
text: '输入、输出系统',
|
||||
prefix: 'basic-introduction',
|
||||
children: []
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
# 计算机组成原理
|
||||
|
||||
|
||||
doing
|
||||
|
||||
### 引论
|
||||
|
||||
### 数据的表示和运算
|
||||
|
||||
### 存储系统
|
||||
|
||||
### 指令系统
|
||||
|
||||
### 中央处理器
|
||||
|
||||
### 总线
|
||||
|
||||
### 输入/输出系统
|
||||
|
||||
|
||||
@@ -1,6 +1,32 @@
|
||||
export const cnSidebar = [
|
||||
{
|
||||
text: '计算机网络',
|
||||
text: '体系结构',
|
||||
prefix: 'basic-introduction',
|
||||
children: []
|
||||
},
|
||||
{
|
||||
text: '物理层',
|
||||
prefix: 'basic-introduction',
|
||||
children: []
|
||||
},
|
||||
{
|
||||
text: '数据链路层',
|
||||
prefix: 'basic-introduction',
|
||||
children: []
|
||||
},
|
||||
{
|
||||
text: '网络层',
|
||||
prefix: 'basic-introduction',
|
||||
children: []
|
||||
},
|
||||
{
|
||||
text: '传输层',
|
||||
prefix: 'basic-introduction',
|
||||
children: []
|
||||
},
|
||||
{
|
||||
text: '应用层',
|
||||
prefix: 'basic-introduction',
|
||||
children: []
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
|
||||
# 计算机网络
|
||||
|
||||
doing
|
||||
|
||||
### 体系结构
|
||||
### 物理层
|
||||
### 数据链路层
|
||||
### 网络层
|
||||
### 传输层
|
||||
### 应用层
|
||||
@@ -1,317 +0,0 @@
|
||||
---
|
||||
title: 基础入门
|
||||
---
|
||||
|
||||
## 基础概念
|
||||
|
||||
### 数据
|
||||
|
||||
**信息的载体**,是客观事物属性的数、字符以及所有能够输入到计算机包中并且被计算机程序识别和处理的**集合**
|
||||
|
||||
### 数据元素
|
||||
|
||||
**数据的基本单位**,通常按照一个整数来进行考虑和处理。
|
||||
|
||||
|
||||
特别注意:一个数据元素由若干个**数据项**组成,数据项是构成数组元素的最小单位,且不可分割。
|
||||
|
||||
|
||||
|
||||
### 数据对象
|
||||
|
||||
具有**相同性质**的数据元素的**集合**,**是数据的子集**
|
||||
|
||||
|
||||
### 数据类型
|
||||
|
||||
值的集合和定义在此集合上一组操作的总称
|
||||
|
||||
- 原子类型:不可再分的数据类型;
|
||||
- 结构类型:可以分解成若干分量(成分)的数据类型;
|
||||
- **抽象数据类型**:抽象出具组织和其相关的操作;
|
||||
|
||||
|
||||
|
||||
### 抽象数据类型(ADT)
|
||||
|
||||
> Tips: 可以结合高级语言中类对象封装来理解;
|
||||
|
||||
```bash
|
||||
ADT抽象数据类型名{
|
||||
数据对象:<数据对象的定义>
|
||||
数据关系:<数据关系的定义>
|
||||
基本操作:<基本操作的定义>
|
||||
} ADT抽象数据类型名
|
||||
```
|
||||
|
||||
|
||||
|
||||
一个数学模型以及定义在该模型上的一组操作。定义仅仅取决于它的一组逻辑操作。与计算机内部如何表示和实现是没有关系;
|
||||
|
||||
**不论内部结构如何变化,只要其数学特性不变,就不会影响到外部的使用,实现了数据封装和信息隐藏**
|
||||
|
||||
|
||||
通常由(数据对象、数据关系、数据操作集)三元组来表示抽象数据类型;
|
||||
|
||||
抽象数据类型的主要作用是**数据封装和信息隐藏,让实现与使用相分离**。数据及其相关操作的结合称为数据封装。对象可以对其他对象隐藏某些操作细节,从而使这些操作不会受到其他对象的影响。
|
||||
|
||||
抽象数据类型独立于运算的具体实现,使用户程序只能通过抽象数据类型定义的某些操作来访问其中的数据,实现了信息隐藏。
|
||||
|
||||
|
||||
### 数据结构
|
||||
|
||||
|
||||
首先明确:数据元素都不是孤立存在的。元素与元素之间存在着某种关系,这种相互之间的关系就是**结构**。
|
||||
|
||||
**数据结构是相互之间存在一种或者多种特定关系的数据元素的集合**
|
||||
|
||||
- 逻辑结构
|
||||
- 存储结构(物理结构)
|
||||
- 数据运算
|
||||
|
||||
数据的逻辑结构和存储结构是密不可分的。
|
||||
|
||||
**算法的设计取决于所选定的逻辑结构;算法的实现依赖于所采用的存储结构;**
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 数据结构三要素
|
||||
|
||||
- 数据的逻辑结构
|
||||
- 数据的存储结构
|
||||
- 数据的运算
|
||||
|
||||
|
||||
### 数据的逻辑结构
|
||||
|
||||
数据元素之间的逻辑关系,从逻辑关系上描述数据,叫做数据的逻辑结构。
|
||||
|
||||
与数据的存储(物理)结构无关,是独立于计算机的。
|
||||
|
||||
可以分为:
|
||||
|
||||
- 线性结构
|
||||
- 非线性结构
|
||||
|
||||
|
||||
线性表是典型的线性结构,衍生出的栈、队列、串、数组、广义表也都是线性结构;
|
||||
|
||||
非线性结构主要有:集合、树(一般树、二叉树)、图(有向图、无向图)
|
||||
|
||||
|
||||
特别注意:
|
||||
|
||||
- `集合`:结构中的数据元素之间**除了“同属于一个集合”的关系外,别无其他关系。**
|
||||
- `线性结构`:结构中的数据元素之间**只存在一对一的关系**。
|
||||
- `树形结构`:结构中的数据元素之间**存在一对多的关系。**
|
||||
- `图状结构和网状结构`:结构中的数据元素之间**存在多对多的关系。**
|
||||
|
||||
|
||||
|
||||
### 数据的存储(物理)结构
|
||||
|
||||
数据结构在计算机中的表示(映像)。包括数据`元素的表示`和`关系的表示`。
|
||||
|
||||
存储结构是逻辑结构用计算机语言实现的,依赖于计算机语言。
|
||||
|
||||
|
||||
可以分为:
|
||||
|
||||
- 顺序存储
|
||||
- 链式存储
|
||||
- 索引存储
|
||||
- 散列(Hash)存储
|
||||
|
||||
**注意:存储和存取的概念不一样**
|
||||
|
||||
#### 顺序存储
|
||||
|
||||
**逻辑上相邻的元素存储在物理位置上也相邻的存储单元里,元素之间的关系由存储单元的邻接关系来体现。**
|
||||
|
||||
优点:
|
||||
|
||||
- 可以实现随机存取
|
||||
- 元素占用最少的存储空间
|
||||
|
||||
缺点:
|
||||
|
||||
- 只能使用相邻的一整块存储单元,依赖于物理结构相邻;
|
||||
- 容易产生`外部碎片`
|
||||
|
||||
什么是内外部碎片?
|
||||
|
||||
> 参考资料:https://blog.csdn.net/qq_22238021/article/details/80209062
|
||||
|
||||
- 外部碎片:`还没有分配出去`(不属于任何进程),但是**由于大小而无法分配给申请内存空间的新进程的内存空闲块。**
|
||||
- 内部碎片:`已经被分配出去`(能明确指出属于哪个进程)的**内存空间大于请求所需的内存空间,不能被利用的内存空间就是内部碎片。**
|
||||
|
||||
|
||||
#### 链式存储
|
||||
|
||||
与顺序存储不同,**链式存储不要求逻辑上相邻的元素在物理位置上也相邻。**
|
||||
|
||||
借助指示元素存储地址的`指针`表示元素之间的逻辑关系。
|
||||
|
||||
|
||||
优点:
|
||||
|
||||
- 不会出现碎片现象
|
||||
- 充分利用所有存储单元
|
||||
|
||||
缺点:
|
||||
|
||||
- 除了存储元素外,还需要额外存储指针,会占用额外的存储空间(结合数据库索引学习)。
|
||||
- 链式存储,**只能实现`顺序存取`,不能实现`随机存取`(指针的遍历)**
|
||||
|
||||
|
||||
#### 索引存储
|
||||
|
||||
存放数据元素和元素间关系的存储方式,在存储元素信息的同时,还需要建立附加的`索引表`。
|
||||
|
||||
**索引表的每一项称为索引项,索引项的一般形式是:<关键字,地址>**
|
||||
|
||||
优点:
|
||||
|
||||
- 检索快(就好比字典有了目录,查询就很快了)
|
||||
|
||||
|
||||
缺点:
|
||||
|
||||
- 增加了索引表,占用较多的存储空间(典型的空间换时间策略)
|
||||
- 增加、删除数据时,需要对应修改索引表,花费更多时间。
|
||||
|
||||
#### 散列(Hash)存储
|
||||
|
||||
根据元素的关键字直接通过散列(Hash)函数计算出元素的存储地址。
|
||||
|
||||
|
||||
优点:
|
||||
|
||||
- 检索快,添加、删除元素结点操作快(获取元素地址直接,整体时间就少了)
|
||||
|
||||
|
||||
缺点:
|
||||
|
||||
- 非常依赖于`散列函数`
|
||||
- 会出现`散列冲突`(主要依赖与散列函数,散列函数不好就很容易出现散列冲突)
|
||||
- 出现`散列冲突`时,解决冲突就会增加时间和空间上的开销
|
||||
|
||||
|
||||
### 数据的运算
|
||||
|
||||
数据上的运算包括:`运算的定义` 、`运算的实现`
|
||||
|
||||
- `运算的定义`:针对逻辑结构,指出运算的功能
|
||||
- `原酸的实现`:针对存储结构,指出运算的具体操作步骤
|
||||
|
||||
|
||||
|
||||
|
||||
线性表既可以用顺序存储方式实现,也可以用链式存储方式实现。
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 算法和算法评价
|
||||
|
||||
|
||||
### 算法
|
||||
|
||||
`算法` : 对特定问题求解步骤的一种描述,**是指令的有序集合**,每一条指令表示一个或多个操作。
|
||||
|
||||
|
||||
#### 重要特性
|
||||
|
||||
- `有穷性`:必须总是(对任何合法的输入值)在**执行有穷步后结束**,并且每一步都可**在有穷时间内完成**
|
||||
- `确定性`:每条指令的含义明确,不会产生二义性(歧义),**对相同的输入只能得出相同的结果**
|
||||
- `可行性`:算法是可行的。**算法中描述的操作都是可以通过已经实现的基本运算执行有限次来实现的**
|
||||
- `输入`:有零个或者多个输入,**输入取决于某个特定的对象的集合。**
|
||||
- `输出`:有一个或者多个输出,**输出是和输入有着某种特定关系的量(强调输出与输入的关系)**
|
||||
|
||||
|
||||
> **算法是有穷的,但是程序不一定满足有穷性**,程序只是算法在计算机上的特定的实现, 例如:死循环
|
||||
|
||||
#### 算法的目标
|
||||
|
||||
由于设计思路、解决问题方案等方面不同,不同算法之间也是有好坏的,就像人与人之间存在着差异。为设计出更好的算算法,往往需要追求更高的目标,而好的算法需要考虑到的目标就有:
|
||||
|
||||
- 正确性:首先算法肯定是**需要正确的解决求解问题**
|
||||
- 可读性:**算法应该具有良好的可读性**,就像项目代码一样,好的业务代码、逻辑清楚,**便于理解**。
|
||||
- 健壮性:**在输入非法数据时,算法也能适当地做出反应或进行处理,而不会产生莫名奇妙的输出结果**(在高级语言编程中,类似于强调封装方法的参数校验)
|
||||
- 效率与低存储量需求:**效率即算法执行的时间**,**存储量需求即算法那执行过程中所有要的最大存储空间**,这些与算法所解决问题的规模有关;
|
||||
|
||||
|
||||
> Tips: 效率可以结合时间复杂度来理解,存储量需求可以结合空间复杂度理解;
|
||||
|
||||
|
||||
### 效率的度量
|
||||
|
||||
算法效率的度量是通过`时间复杂度`和`空间复杂度`来描述的;
|
||||
|
||||
#### 时间复杂度
|
||||
|
||||
语句的频度:语句在算法中被重复执行的次数
|
||||
|
||||
算法中所有语句的`频度之和`记作T(n),即:对应算法问题规模n的函数,时间复杂度主要是来分析T(n)的数量级;
|
||||
|
||||
**算法的时间复杂度不仅依赖于问题的规模n,也取决于待输入的数据的性质(例如:输入元素的初始状态)**
|
||||
|
||||
上面这句话是不是不能理解??? 哈哈哈,我第一次看,也是!!
|
||||
|
||||
```c
|
||||
|
||||
int test(n) {
|
||||
if(n< 1){
|
||||
return 0;
|
||||
}
|
||||
// 循环叠加 输出
|
||||
.....
|
||||
}
|
||||
|
||||
|
||||
|
||||
```
|
||||
在这个简单的函数里
|
||||
|
||||
- 当n<1的时候,例如:-2,就不需要循环,此时时间复杂度可以理解为T(1)
|
||||
- 当n>1的时候,例如:5 此时时间复杂度可以理解为T(n)
|
||||
|
||||
当然,这里只是简单举例子便于理解:
|
||||
|
||||
> **算法的时间复杂度不仅依赖于问题的规模n,也取决于待输入的数据的性质(例如:输入元素的初始状态)**
|
||||
|
||||
|
||||
|
||||
- `最坏时间复杂度`:**最坏情况下**,算法的时间复杂度
|
||||
- `平均时间复杂度`:**所有可能输入实例在同等概率出现的情况下**,算法的期望运行时间
|
||||
- `最好时间复杂度`:**最好的情况下**,算法的时间复杂度
|
||||
|
||||
|
||||
一般情况下,考虑最坏情况的时间复杂度(即:最坏时间复杂度),保证算法的运行时间不会更长(最糟糕我都能预料,难道还有更糟糕?????噗呲)
|
||||
|
||||
#### 空间复杂度
|
||||
|
||||
算法的空间复杂度可以用函数记作:S(n),**用来定义算法运行过程中需要耗费的存储空间**,是问题规模n的函数;
|
||||
|
||||
> 渐进空间复杂度也被称为空间复杂度,记作:S(n)=O(g(n))
|
||||
|
||||
|
||||
**一个程序除了需要存储空间来存放本身所用的指令、常数、变量和输入数据外,也需要对数据进行操作的工作单元和存储一些实现计算所需要信息的辅助空间。**
|
||||
|
||||
当输入数据所占用的空间只取决于问题本身,和算法无关时,只需要去分析除了输入和程序之外的额外空间
|
||||
|
||||
|
||||
|
||||
算法原地工作:算法所需要辅助空间是常量,记作S(1),例如:
|
||||
|
||||
```c
|
||||
int switchValue(a,b){
|
||||
// 定义临时变量
|
||||
int temp=a;
|
||||
b=temp;
|
||||
a=b;
|
||||
}
|
||||
```
|
||||
|
||||
在上面的函数中,只是通过临时变量temp来实现a和b的值交换,没有需要更多变量,因此可以简单理解函数的在`原地工作`,辅助空间是常量,记作S(1)
|
||||
@@ -1,4 +0,0 @@
|
||||
|
||||
# 算法恶补
|
||||
|
||||
>todo
|
||||
@@ -58,7 +58,7 @@ export const dsSidebar = [
|
||||
collapsible: false,
|
||||
children: [
|
||||
{
|
||||
text: '栈-基本概念和基本操作',
|
||||
text: '栈-基本概念和操作',
|
||||
link: '1.栈的基本概念和基本操作.md'
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# 线性表的基础概念和基本操作
|
||||
# 线性表的基础概念和操作
|
||||
|
||||
> 强调线性表是一种逻辑结构,不是存储结构
|
||||
|
||||
|
||||
@@ -1,317 +0,0 @@
|
||||
|
||||
# 线性表
|
||||
|
||||
## 基础概念和基本操作
|
||||
|
||||
> 强调线性表是一种逻辑结构,不是存储结构
|
||||
|
||||
|
||||
### 定义
|
||||
|
||||
线性表是具有相同数据类型的n(n≥0)个数据元素的有限序列。一般表示:
|
||||
|
||||
L=(a<sub>1</sub>,a<sub>2</sub>,a<sub>3</sub>......a<sub>n</sub>) 其中n可以理解为表长(线性表的长度),n=0时候,即表空
|
||||
|
||||
|
||||
- `表头元素`:线性表中唯一的“第一个”数据元素,例如a<sub>1</sub>
|
||||
- `表尾元素`:线性表中唯一的“最后一个”数据元素,例如a<sub>n</sub>
|
||||
|
||||
|
||||
重要逻辑特性:
|
||||
|
||||
- 除表头元素外,线性表中每个元素有且仅有一个`直接前驱`
|
||||
- 除表尾元素外,线性表中每个元素有且仅有一个`直接后继`
|
||||
|
||||
基于此,这种**线性有序的逻辑结构**,使得线性表的特点如下:
|
||||
|
||||
- 元素的**个数有限**(强调有限序列)
|
||||
- 元素在逻辑上具有**顺序性**,在序列中每个元素都是都有先后次序的
|
||||
- 元素都数据元素,**每个元素都是单个元素**
|
||||
- 元素的**数据类型都相同**(强调相同数据类型),每个数据元素占用相同大小的存储空间
|
||||
- 元素具有**抽象性**,仅仅讨论元素之间的逻辑关系,不需要去考虑元素究竟表示的什么内容
|
||||
|
||||
|
||||
> Tips: **线性表是一种逻辑结构**,表示元素之间一对一的相邻关系。**顺序表和链表则指的是存储结构**
|
||||
|
||||
|
||||
|
||||
### 基本操作
|
||||
|
||||
- `InitList(&L)`: **初始化表**。构造空的线性表
|
||||
- `Length(L)`:**获取表的长度**。返回线性表L的长度,即表中的数据元素个数
|
||||
- `LocateElem(L,e)`:**按值查找操作**。在表L中国查找具有给定关键字的元素
|
||||
- `GetElem(L,i)`:**按位查找操作**。获取表中第i个位置的元素的值
|
||||
- `ListInsert(&L,i,e)`:**插入操作**。在表的第i个位置上插入指定元素e
|
||||
- `ListDelete(&L,i,&e)`:**删除操作**。删除表中第i个位置的元素,并用e返回删除元素的值
|
||||
- `PrintList(L)`:**输出操作**。按照前后顺序(如:1、2....n)输出线性表的所有元素值
|
||||
- `Empty(L)`:**判空操作**。当表L为空,则返回true,否则返回false
|
||||
- `DestoryList(&L)`:**销毁操作**。将线性表销毁,释放线性表L所占用的内存空间(类似:释放内存)
|
||||
|
||||
|
||||
线性表是具有相同的数据类型的有限个数据元素组成的,**数据元素是由数据项组成的**
|
||||
|
||||
|
||||
## 线性表的顺序表示
|
||||
|
||||
|
||||
### 定义
|
||||
|
||||
`顺序表`:顺序存储的线性表,**是用一组地址连续的存储单元,依次存储线性表中的数据元素,使得在逻辑上相邻的两个元素在物理位置上也相邻。**
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
顺序表中的元素的逻辑顺序与实际的物理位置相同
|
||||
|
||||
|
||||
|
||||
注意:
|
||||
|
||||
- 线性表中的元素的位序是从1开始的,例如1、2、3...
|
||||
- 数组中的元素的下标是从0开始的,例如0、1、2...
|
||||
|
||||
```c
|
||||
# define MaxSize 20 // 定义常量MaxSize 用来声明顺序表的最大长度
|
||||
|
||||
// 线性表结构体定义【ElemType用来代指顺序表中元素的类型,例如高级语言中的int、string....】
|
||||
typedef struct{
|
||||
ElemType data[MaxSize]; // 顺序表的元素
|
||||
int length; // 顺序表的长度
|
||||
}SqList
|
||||
|
||||
```
|
||||
|
||||
#### 存储分配
|
||||
|
||||
`静态分配`:数组的大小和空间都是实现确定好的,一旦存储空间占满就会产生溢出,直接导致程序崩溃。(有点内存不够,宕机重启的意思....)
|
||||
|
||||
`动态分配`:存储数据的空间在程序执行过程中通过`动态存储分配语句`分配的,即便是数据空间占满,也可以另外开辟一块更大的空间,来替换原来的存储空间,满足扩充数据空间的目的。(有点动态规划的意思....)最重要的是:**不需要像静态分配那样,一次性地固定线性表的空间和大小**
|
||||
|
||||
|
||||
|
||||
```c
|
||||
#define InitSize 100 // 表长度初始化
|
||||
|
||||
|
||||
// 动态分配数组顺序表的结构体定义
|
||||
typedef struct{
|
||||
ElemType *data; // 动态分配数组的指针
|
||||
int MaxSize,length; // 数组的最大容量和当前元素个数
|
||||
}SqList;
|
||||
|
||||
```
|
||||
|
||||
动态分配语句
|
||||
|
||||
```cpp
|
||||
// C语言中
|
||||
|
||||
L.data=(ElemType*)malloc(sizeof(ElemType)*InitSize);
|
||||
|
||||
|
||||
// C++ 中
|
||||
|
||||
L.data=new ElemType[InitSize];
|
||||
|
||||
```
|
||||
|
||||
`malloc()函数`: 指针型函数,返回的指针指向该分配域的开头的位置。作用是在内存的动态存储区中分配一个长度为size的连续空间。[百度百科](https://baike.baidu.com/item/malloc%E5%87%BD%E6%95%B0/8582146?fr=aladdin)
|
||||
|
||||
**动态分配不是链式存储,而是属于顺序存储结构**,动态分配的物理结构没有改变,依然是随机存取的方式。只是分配的空间大小可以在运行时决定;
|
||||
|
||||
|
||||
#### 顺序表的特点
|
||||
|
||||
|
||||
- 随机访问【这是最主要的特点】,通过存储起始地址和元素序号O(1)时间内访问指定元素。
|
||||
- 存储密度高,没有结点只存储数据元素,不像索引存储那样,还需要索引表什么的..
|
||||
- 逻辑上相邻的元素物理上也相邻,插入和删除需要移动大量元素
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 基本操作
|
||||
|
||||
|
||||
#### 插入
|
||||
|
||||
在顺序表L的第i(1≤i≤L.length+1)个位置插入新的元素e
|
||||
|
||||
- 第一步:如果i非法,则直接返回false,插入失败,结束插入过程
|
||||
- 第二步:i正常,将表的第i个元素以及后面的所有元素都像有移动一个位置,在腾出来的空位置插入元素e
|
||||
- 第三步:顺序表插入成功,返回true
|
||||
|
||||
注意:先判空和临界值,提高算法健壮性
|
||||
|
||||
```cpp
|
||||
|
||||
/*
|
||||
* @Description: 顺序表的插入操作
|
||||
* @Version: Beta1.0
|
||||
* @Author: 【B站&公众号】Rong姐姐好可爱
|
||||
* @Date: 2020-02-23 07:48:26
|
||||
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
|
||||
* @LastEditTime: 2020-02-23 07:48:26
|
||||
*/
|
||||
bool ListInsert(SqList &L, int i, ElemType e){
|
||||
|
||||
// i非法 i=1 表头 i=L.length+1 表尾巴
|
||||
if(i<1||i>L.length+1){
|
||||
return false;
|
||||
}
|
||||
|
||||
// 存储空间满,无法插入
|
||||
if(L.length >= MaxSize){
|
||||
return false;
|
||||
}
|
||||
|
||||
// 遍历,将位置元素往后移动,注意从后往前循环,避免值被覆盖
|
||||
for(int j=L.length; j>=i;j--){
|
||||
L.data[j]=L.data[j-1];
|
||||
}
|
||||
|
||||
// 此时,表L中的第i个元素和第i+1元素素值一样,将新元素存入i位置即可
|
||||
|
||||
// 第i个元素,对应的位置角标为i-1
|
||||
L.data[i-1]=e;
|
||||
|
||||
// 表长度加1
|
||||
L.length++;
|
||||
|
||||
// 返回插入成功
|
||||
return true;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
注意:区别顺序表中的位序和角标;
|
||||
|
||||
**时间复杂度**
|
||||
|
||||
- 最好情况:在表尾插入,元素向后移动循环没有执行,时间复杂度O(1);
|
||||
- 最坏情况:在表头插入,元素后移循环执行n次,时间复杂度为O(n);
|
||||
- 平均情况:随机插入,平均次数为:n/2,对应的平均复杂度为O(n);
|
||||
|
||||
|
||||
**线性表插入算法的平均时间复杂度为:O(n)**
|
||||
|
||||
> Tips: 需要根据实现代码理解循环为什么是从后往前来实现元素后移,通过for循环可以很明显的看出表尾插入快,表头插入慢
|
||||
|
||||
#### 删除
|
||||
|
||||
删除顺序表L中第i(1≤i≤L.length+1)个位置的元素
|
||||
|
||||
- 成功,返回true,将被删除的元素用引用变量返回;
|
||||
- 失败,返回false
|
||||
|
||||
```cpp
|
||||
|
||||
/*
|
||||
* @Description: 顺序表的删除操作
|
||||
* @Version: Beta1.0
|
||||
* @Author: 【B站&公众号】Rong姐姐好可爱
|
||||
* @Date: 2020-02-23 07:48:26
|
||||
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
|
||||
* @LastEditTime: 2020-02-23 07:48:26
|
||||
*/
|
||||
bool ListDelete(SqList &L, int i, ElemType &e){
|
||||
|
||||
// i非法 i=1 表头 i=L.length+1 表尾巴
|
||||
if(i<1||i>L.length+1){
|
||||
return false;
|
||||
}
|
||||
|
||||
// 存储空间满,无法插入
|
||||
if(L.length >= MaxSize){
|
||||
return false;
|
||||
}
|
||||
|
||||
// 引用变量e赋值
|
||||
e=L.data[i-1]
|
||||
|
||||
// 遍历,第i个元素后面的往前移动
|
||||
for(int j=i; j<=L.length;j++){
|
||||
// 从第i个元素开始,角标从i-1开始
|
||||
L.data[j-1]=L.data[j];
|
||||
}
|
||||
|
||||
// 此时,表L中的表尾元素和倒数第二个元素值一样,将表的长度-1
|
||||
|
||||
// 表长度减1
|
||||
L.length--;
|
||||
|
||||
// 返回删除成功
|
||||
return true;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
从这里来看,删除、插入元素都会涉及到大量的元素的移动(最好情况例外),总结而言:
|
||||
- 元素从后往前移,循环从前往后遍历
|
||||
- 元素从前往后移,循环从后往前遍历
|
||||
|
||||
|
||||
**时间复杂度:**
|
||||
|
||||
|
||||
- 最好情况:删除表尾元素,不需要移动任何元素,时间复杂度为O(1);
|
||||
- 最坏情况:删除表头元素,需要移动除第一个元素外的所有元素,时间复杂度为O(n);
|
||||
- 平均情况:随机删除,平均需要(n-1)/2,对应的时间复杂度为O(n);
|
||||
|
||||
|
||||
|
||||
**线性表删除算法的平均时间复杂度为O(n);**
|
||||
|
||||
|
||||
#### 按值查找(顺序查找)
|
||||
|
||||
在顺序表L中查找第一个元素值等于e的元素,并返回位序
|
||||
|
||||
|
||||
```cpp
|
||||
/*
|
||||
* @Description: 顺序表的按值查找(顺序查找)
|
||||
* @Version: Beta1.0
|
||||
* @Author: 【B站&公众号】Rong姐姐好可爱
|
||||
* @Date: 2020-02-23 07:48:26
|
||||
* @LastEditors: 【B站&公众号】Rong姐姐好可爱
|
||||
* @LastEditTime: 2020-02-23 07:48:26
|
||||
*/
|
||||
int LocateElem(SqList L,ElemType e){
|
||||
int i;
|
||||
// 循环判断
|
||||
for(i=0;i<L.length;i++){
|
||||
if(L.data[i]===e){
|
||||
// i是元素的角标,i+1是具体元素的位序号
|
||||
return i+1;
|
||||
}
|
||||
}
|
||||
|
||||
// 未命中,返回0,即:没有
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
注意理解`位序`的含义,即元素在线性表中的位置序号,角标为`i`(角标从0开始),对应的位序为`i+1`(位序从1开始)。当返回为0时,则直接代表没有`命中`;
|
||||
|
||||
|
||||
**时间复杂度:**
|
||||
|
||||
- 最好情况:查找的元素在表头,只需要比较一次,循环成本最小,时间复杂度为O(1);
|
||||
- 最坏情况:查找的元素在表尾或者不存在,需要完整遍历,比较n次,时间复杂度为O(n);
|
||||
- 平均情况:随机查找表上的第i个(1≤i≤L.length)元素,平均次数为(n+1)/2,对应时间复杂度为O(n)
|
||||
|
||||
|
||||
|
||||
**线性表按值查找(顺序查找)的平均时间复杂度为O(n);**
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**顺序存取是读写方式,不是存储结构;顺序存储是存储结构,包括有:顺序存储、链式存储、索引存储、散列存储**
|
||||
@@ -1,75 +1,31 @@
|
||||
# 数据结构
|
||||
|
||||
```mindmap
|
||||
root(数据结构)
|
||||
|
||||
基础入门
|
||||
基本概念
|
||||
数据结构三要素
|
||||
算法和算法评价
|
||||
|
||||
线性表
|
||||
基础概念和操作
|
||||
线性表的顺序表示
|
||||
基础概念和操作
|
||||
基础概念和操作
|
||||
基础概念和操作
|
||||
基础概念和操作
|
||||
基础概念和操作
|
||||
存储结构的选取
|
||||
零碎知识补充
|
||||
|
||||
栈和队列
|
||||
栈的基本概念和基本操作
|
||||
栈的基本概念和基本操作
|
||||
栈的顺序存储结构
|
||||
栈的链式存储结构
|
||||
队列的基本概念和操作
|
||||
队列的顺序存储结构
|
||||
队列的链式存储结构
|
||||
栈和队列的应用
|
||||
特殊矩阵的压缩存储
|
||||
```
|
||||
|
||||
|
||||
### 基础入门
|
||||
|
||||
- [ ] 基本概念
|
||||
- [ ] 数据结构三要素
|
||||
- [ ] 算法和算法评价
|
||||
- [x] 基本概念
|
||||
- [x] 数据结构三要素
|
||||
- [x] 算法和算法评价
|
||||
|
||||
|
||||
### 线性表
|
||||
|
||||
- [ ] 基础概念和操作
|
||||
- [ ] 线性表的顺序表示
|
||||
- [ ] 基础概念和操作
|
||||
- [ ] 基础概念和操作
|
||||
- [ ] 基础概念和操作
|
||||
- [ ] 基础概念和操作
|
||||
- [ ] 基础概念和操作
|
||||
- [ ] 存储结构的选取
|
||||
- [ ] 零碎知识补充
|
||||
- [x] 基础概念和操作
|
||||
- [x] 顺序表示
|
||||
- [x] 链式表示-单链表
|
||||
- [x] 链式表示-双链表
|
||||
- [x] 链式表示-循环链表
|
||||
- [x] 链式表示-静态链表
|
||||
- [x] 总结
|
||||
|
||||
### 栈和队列
|
||||
|
||||
|
||||
#### 栈
|
||||
|
||||
- [ ] 栈的基本概念和基本操作
|
||||
- [ ] 栈的基本概念和基本操作
|
||||
- [ ] 栈的顺序存储结构
|
||||
- [ ] 栈的链式存储结构
|
||||
|
||||
#### 队列
|
||||
|
||||
- [ ] 队列的基本概念和操作
|
||||
- [ ] 队列的顺序存储结构
|
||||
- [ ] 队列的链式存储结构
|
||||
- [ ] 栈和队列的应用
|
||||
- [ ] 特殊矩阵的压缩存储
|
||||
|
||||
|
||||
- [x] 栈-基本概念和操作
|
||||
- [x] 栈-顺序存储结构
|
||||
- [x] 栈-链式存储结构
|
||||
- [x] 队列-基本概念和操作
|
||||
- [x] 队列-顺序存储结构
|
||||
- [x] 队列-链式存储结构
|
||||
- [x] 总结
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
# 计算机组成原理
|
||||
|
||||
<iframe
|
||||
:src="$withBase('../../mark-map/ccp-map.html')"
|
||||
width="100%"
|
||||
height="800"
|
||||
frameborder="0"
|
||||
scrolling="No"
|
||||
leftmargin="0"
|
||||
topmargin="0"
|
||||
/>
|
||||
<a href="../../mark-map/ccp-map.html" target="_blank">在线预览</a>
|
||||
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
# 计算机网络
|
||||
|
||||
<iframe
|
||||
:src="$withBase('../..//mark-map/cn-map.html')"
|
||||
width="100%"
|
||||
height="800"
|
||||
frameborder="0"
|
||||
scrolling="No"
|
||||
leftmargin="0"
|
||||
topmargin="0"
|
||||
/>
|
||||
<a href="../../mark-map/cn-map.html" target="_blank">在线预览</a>
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,15 +1,23 @@
|
||||
export const noteMapSidebar = [
|
||||
/**
|
||||
* 思维导图侧边栏
|
||||
*/
|
||||
export const MarkMapSidebar = [
|
||||
{
|
||||
text: '数据结构',
|
||||
link: 'ds-map.md'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
text: '操作系统',
|
||||
link: 'os-map.md'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
text: '计算机组成原理',
|
||||
link: 'ccp-map.md'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
text: '计算机网络',
|
||||
link: 'cn-map.md'
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
# 操作系统
|
||||
|
||||
<iframe
|
||||
:src="$withBase('../../mark-map/os-map.html')"
|
||||
width="100%"
|
||||
height="800"
|
||||
frameborder="0"
|
||||
scrolling="No"
|
||||
leftmargin="0"
|
||||
topmargin="0"
|
||||
/>
|
||||
|
||||
<a href="../../mark-map/os-map.html" target="_blank">在线预览</a>
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# 思维导图
|
||||
|
||||
> 思维导图汇总整理,内容更新慢于笔记,赶稿中...
|
||||
|
||||
- <a href="../../mark-map/ds-map.html" target="_blank">数据结构</a>
|
||||
- <a href="../../mark-map/os-map.html" target="_blank">操作系统</a>
|
||||
- <a href="../../mark-map/ccp-map.html" target="_blank">计算机组成原理</a>
|
||||
|
||||
@@ -13,4 +13,23 @@
|
||||
文件管理
|
||||
|
||||
I/O管理
|
||||
```
|
||||
```
|
||||
|
||||
|
||||
### 系统概述
|
||||
|
||||
- 引论
|
||||
- 发展和分类
|
||||
- 运行环境
|
||||
- 体系结构
|
||||
|
||||
### 进程管理
|
||||
|
||||
- 进程基本概念和特征
|
||||
- 进程的运行
|
||||
|
||||
### 进程管理
|
||||
|
||||
### 文件管理
|
||||
|
||||
### I/O管理
|
||||
@@ -1,3 +1,2 @@
|
||||
---
|
||||
title: 笔记
|
||||
---
|
||||
# 笔记
|
||||
|
||||
|
||||
Reference in New Issue
Block a user