Merge branch 'master' of gitee.com:Eyestorm/notes

This commit is contained in:
estomm
2021-03-13 22:16:47 +08:00
130 changed files with 6709 additions and 93 deletions

30
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,30 @@
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "g++.exe - 生成和调试活动文件",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "D:\\mingw\\mingw64\\bin\\gdb.exe",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "C/C++: g++.exe 生成活动文件"
}
]
}

46
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,46 @@
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++.exe 生成活动文件",
"command": "D:\\mingw\\mingw64\\bin\\g++.exe",
"args": [
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [
"$gcc"
],
"group": "build",
"detail": "调试器生成的任务。"
},
{
"type": "cppbuild",
"label": "C/C++: g++.exe 生成活动文件 ver(1)",
"command": "D:\\mingw\\mingw64\\bin\\g++.exe",
"args": [
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "调试器生成的任务。"
}
],
"version": "2.0.0"
}

View File

@@ -31,7 +31,7 @@
![](2021-03-05-20-42-30.png)
> 操作记忆
> * back、front、push_back、push_front、pop_back、pop_front。是一组首尾相关的操作。
> * back、front、push_back、push_front、pop_back、pop_front、emplace_front、emplace_back。是一组首尾相关的插入操作。
> * insert、at、erase。是一组随机的操作。
@@ -48,6 +48,12 @@
> 与数组完全一致,只是定义方式不同。
> 数组不能copy赋值但是array可以copy赋值。
### 定义
```
array<int, 5> arr = {1, 2, 3, 4, 5};
```
## 2 vector
## 3 deque

View File

@@ -29,24 +29,38 @@
| 3 | 排序算法Sorting/Partitions/Binary search/(对序列排序、合并、搜索算法操作。) |
| 4 | 数值算法Merge/Heap/Min/max(对容器内容进行数值计算。) |
## 1.1 基础算法
### 填充
### 参数说明
|参数|说明|
|----|----|
beg|开始迭代器
end|终止迭代器
val|值
func|操作函数
n|整数
comp|比较函数,返回true/false
binary|判断函数,返回true/false
## 1.1 基础算法(遍历算法)
### 检查
* 检查谓词是否对范围中所有、任一或无元素为 true
| 函数 | 作用 |
|---|---|
| fill(beg,end,val) | 将值val赋给[beg,end)范围内的所有元素|
| fill_n(beg,n,val) | 将值val赋给[beg,beg+n)范围内的所有元素。 |
| generate(beg,end,func) | 连续调用函数func填充[beg,end)范围内的所有元素。 |
| generate_n(beg,n,func) | 连续调用函数func填充[beg,beg+n)范围内的所有元素。 |
|all_of(beg,end,binary)|检查所有元素是否满足binary|
|any_of(beg,end,binary)|检查任意的元素是否满足binary|
|none_of(beg,end,binary)|检查没有元素满足binary|
### 遍历变换
### 遍历变换
| 函数 | 作用 |
|---|---|
| for_each(beg,end,func) | 将[beg,end)范围内所有元素依次调用函数func返回func。不修改序列中的元素。 |
| transform(beg,end,res,unary) | 将[beg,end)范围内所有元素依次调用函数unary结果放入res中。 |
| transform(beg2,end1,beg2,res,binary) | 将[beg,end)范围内所有元素与[beg2,beg2+end-beg)中所有元素依次调用函数unary结果放入res中。 |
| transform(beg1,end1,beg2,res,binary) | 将[beg,end)范围内所有元素与[beg2,beg2+end-beg)中所有元素依次调用函数unary结果放入res中。 |
### 最大最小
| 函数 | 作用 |
@@ -59,6 +73,10 @@
| min(a,b,cmp) | 使用自定义比较操作cmp,返回两个元素中较小一个。 |
| min_element(beg,end) | 返回一个ForwardIterator指出[beg,end)中最小的元素。 |
| min_element(beg,end,cmp) | 使用自定义比较操作cmp,返回一个ForwardIterator指出[beg,end)中最小的元素。 |
|minmax(beg,end)|返回一个pair包含最小最大值|
|minmax(beg,end,cmp)|自定义比较函数|
|minmax_element(beg,end)|返回一个pair包含最大最小值的位置|
|minmax_element(beg,end,cmp)|自定义比较函数|
## 1.2 排序算法12个
@@ -106,7 +124,7 @@
| count(beg,end,val) | 利用==操作符,对[beg,end)的元素与val进行比较返回相等元素个数。 |
| count_if(beg,end,pred) | 使用函数pred代替==操作符执行count()。 |
### 查找
### 查找(查找某个值)
| 函数 | 作用 |
|---|---|
@@ -119,7 +137,7 @@
| adjacent_find(beg,end) | 对[beg,end)的元素查找一对相邻重复元素找到则返回指向这对元素的第一个元素的ForwardIterator。否则返回end。 |
| adjacent_find(beg,end,pred) | 使用函数pred代替==操作符执行adjacent_find()。 |
### 搜索
### 搜索(搜索某个序列)
| 函数 | 作用 |
|---|---|
@@ -141,7 +159,17 @@
| equal_range(beg,end,val) | 返回一对iterator第一个表示lower_bound第二个表示upper_bound。 |
| equal_range(beg,end,val,comp) | 使用函数comp代替比较操作符执行lower_bound()。 |
## 1.4 删除和替换算法15
## 1.4 填充复制移除替换算法19
### 填充
| 函数 | 作用 |
|---|---|
| fill(beg,end,val) | 将值val赋给[beg,end)范围内的所有元素。 |
| fill_n(beg,n,val) | 将值val赋给[beg,beg+n)范围内的所有元素。 |
| generate(beg,end,func) | 连续调用函数func填充[beg,end)范围内的所有元素。 |
| generate_n(beg,n,func) | 连续调用函数func填充[beg,beg+n)范围内的所有元素。 |
### 复制
@@ -185,7 +213,9 @@
| swap_range(beg1,end1,beg2) | 将[beg1,end1)内的元素[beg2,beg2+beg1-end1)元素值进行交换。 |
| iter_swap(it_a,it_b) | 交换两个ForwardIterator的值。 |
## 1.5 算算法4个
## 1.5 算算法4个
`#inlcude<numeric>`
| 函数 | 作用 |
|---|---|
@@ -239,12 +269,14 @@
| 函数 | 作用 |
|---|---|
|is_heap(beg,end[,comp]) | 检查给定范围是否为一个最大堆|
|is_heap_until(beg,end[,comp]) | 查找能成为最大堆的最大子范围|
| make_heap(beg,end) | 把[beg,end)内的元素生成一个堆。 |
| make_heap(beg,end,comp) | 将函数comp代替<操作符执行make_heap()。 |
| pop_heap(beg,end) | 重新排序堆。它把first和last-1交换然后重新生成一个堆。可使用容器的back来访问被"弹出"的元素或者使用pop_back进行真正的删除。并不真正把最大元素从堆中弹出。 |
| pop_heap(beg,end,comp) | 将函数comp代替<操作符执行pop_heap()。 |
| push_heap(beg,end) | 假设first到last-1是一个有效堆要被加入到堆的元素存放在位置last-1重新生成堆。在指向该函数前必须先把元素插入容器后。 |
| push_heap(beg,end,comp) | 将函数comp代替<操作符执行push_heap()。 |
| pop_heap(beg,end) | 重新排序堆。它把first和last-1交换然后重新生成一个堆。可使用容器的back来访问被"弹出"的元素或者使用pop_back进行真正的删除。并不真正把最大元素从堆中弹出。 |
| pop_heap(beg,end,comp) | 将函数comp代替<操作符执行pop_heap()。 |
| sort_heap(beg,end) | 对[beg,end)内的序列重新排序。 |
| sort_heap(beg,end,comp) | 将函数comp代替<操作符执行push_heap()。 |

View File

@@ -0,0 +1,20 @@
# 临时对象
### 定义
* C++直接调用构造函数。会创建临时对象。
* 临时对象没有对象名,它的生命周期只有一条语句。
* 如果直接调用构造函数,赋值给一个具体的名字,则会使用复制初始化。则不是临时对象。
### 使用
* 如果做为函数参数使用。调用的是复制噶偶早函数。
```
vector<vector<int> > vec;
vec.push_back(vector<int>(5));//直接调用构造函数,会创建临时对象。
```
* 如果作为返回值使用。调用的是复制构造函数。
```
vector<int> hello(){
return vector<int>();
}
```

View File

@@ -3,7 +3,7 @@
### 基础
可以把主存看成一本空白bai的作业本,你现在要在笔记本上记录一些内容,他的页码排序是
可以把主存看成一本空白的作业本,你现在要在笔记本上记录一些内容,他的页码排序是
```
第一页 : 0x0000001
@@ -13,12 +13,12 @@
```
1. 如果你选择`从前向后记录`(用完第一页,用第二页,类推)这就是先使用低地址,后使用高地址.业内表述:动态分配内存时堆空间向高地址增长,说的就是这种情况.这个向高地址增长就是先使用低地址,后使用高地址的意思.
1. 如果你选择`从前向后记录`(用完第一页,用第二页,类推)这就是先使用低地址,后使用高地址.业内表述:动态分配内存时**堆空间向高地址增长**,说的就是这种情况.这个向高地址增长就是先使用低地址,后使用高地址的意思.
```
0x0000001 -> 0x0000002-> ... -> 0x0000092
```
1. 如果你选择`从后往前记录`(先用笔记本的最后一页,用完后使用倒数第二页,类推) 这就是先使用高地址,后使用低地址.业内表述:`0xbfac 5000-0xbfad a000`是栈空间,其中高地址的部分保存着进程的环境变量和命令行参数,低地址的部分保存函数栈帧,**栈空间是向低地址增长的**.这个向低地址增长就是先使用高地址,后使用低地址的意思.
2. 如果你选择`从后往前记录`(先用笔记本的最后一页,用完后使用倒数第二页,类推) 这就是先使用高地址,后使用低地址.业内表述:`0xbfac 5000-0xbfad a000`是栈空间,其中高地址的部分保存着进程的环境变量和命令行参数,低地址的部分保存函数栈帧,**栈空间是向低地址增长的**.这个向低地址增长就是先使用高地址,后使用低地址的意思.
```
0x0000092 -> ... ->0x0000002 -> 0x0000001
```

View File

@@ -1,13 +1,12 @@
\>程序控制结构简写
\>\>if-else条件判断选择
## 程序控制结构简写
### if-else条件判断选择
```
if判断条件{分支1}
else {分支2}
\>\>switch多项选择结构注意关键字default、break
```
### switch多项选择结构注意关键字default、break
```
switch(选择变量){
case 1:分支1;break;
@@ -19,43 +18,58 @@ case 3:分支3break;
default:分支4
}
```
\>\>for(初始化;循环条件;循环控制){
### for循环
```
for(初始化;循环条件;循环控制){
循环体;
}
```
\>\>while(判断语句){循环体}
### while循环
\>\>关键字continue(退出本次循环开始新的循环)
```
while(判断语句){循环体}
```
* 关键字continue(退出本次循环开始新的循环)
\>\>关键字break退出整个循环
* 关键字break退出整个循环
\>JS中的函数
\>\>函数的定义:
## 2 JS中的函数
### 函数的定义:
```
function fun(){函数体}
\>\>函数调用
```
### 函数调用
```
函数名(实际参数);
\>\>参数传递
```
### 参数传递
```
可以传递任意数量的参数, 不用声明参数类型
\>\>函数返回值
```
### 函数返回值
```
可以返回任意类型的返回值。
```
### 函数声明
```
是函数在任何地方都可以定义
```
### 函数作用域
```
全局函数,对象的函数
```
### this
* 函数体中this说明当前函数方法的作用域。可以是全局作用域可以是整个windows对象可能用于指向函数外部的变量。
\>\>函数声明,是函数在任何地方都可以定义
### call
* call(this的指向 变量)可以改变当前函数中this的指向
\>\>函数作用域,全局函数,对象的函数
\>\>this函数体中this说明当前函数方法的作用域。可以是全局作用域可以是整个windows对象可能用于指向函数外部的变量。
\>\>call(this的指向 变量)可以改变当前函数中this的指向
\>\>apply(this的指向数组)改变当前函数中this的指向
### apply
* apply(this的指向数组)改变当前函数中this的指向

View File

@@ -7,9 +7,9 @@
### 工作
- 制作简历(明天)
- 知识复习——语言(一周)
- C++primer
- 制作简历(明天)
- 知识复习——语言
- C++primer(两周)
- 基础语法√
- 标准库 STL√
- 面向对象√
@@ -17,12 +17,43 @@
- effective 系列
- 系列视频
- 问题专项解决)
- Java语法、标准库
- 知识复习——算法(一周)
- 数据结构
- 算法
- Java两周
- 语法
- 标准库网络编程、多线程、IO
- Spring框架
- 知识复习——算法与数据结构(一周)
- 数据结构《大话数据结构》
- 算法《数据结构与算法分析》《算法图解》
- 知识复习——基础(一周)
- 计算机网络
- 数据库
- 操作系统
- Linux 与网络编程
* 刷题
* 力扣(学习、题库、讨论。侧重于刷算法类型的题目和相关讨论)
* 学习3-5本书的学习需要阅读的书籍如下
* 数组、链表、队列、树(堆)、图(数据结构专项)
* 初级算法
* 中级算法
* 高级算法
* 题库:然后按照热度刷题库
* 剑指offer
* 讨论:没事看讨论,主要是一些面经和基础知识,可以补充
* 牛客网(学习、社区、求职基础知识的学习)
* 题库(知识用来刷题)
* 经典必刷题目
* C++/JAVA专项练习
### 问题(待处理)
* 关于递归的方式。头递归。尾递归。递归前和递归后的处理。递归前的处理,影响或许递归。递归后的处理,恢复之前的影响。那个应该是一个典型的递归搜索路径的问题。
* 关于树的处理。前序遍历中序遍历后续遍历。
* 关于位运算的特殊总结。
### 时间安排
* 知识复习——数据结构与算法
* 明天早上,根据已经下载好的笔记,读博客已经收藏的博客,修改笔记。关键部分写代码。
* 刷题——剑指offer、经典必刷提、C++专项练习。

View File

@@ -0,0 +1,78 @@
## 数据结构基础
> 参考文献
> * [易佰教程](https://www.yiibai.com/data_structure)
## 1 简介
### 数据结构预算法
![](数据结构与算法.jpeg)
### 基本术语
数据结构是任何程序或软件的构建块(基础块)。为程序选择适当的数据结构对于程序员来说是最困难的任务。就数据结构而言,使用以下术语 -
* 数据数据可以定义为基本值或值集合例如学生的姓名和ID成绩等就是学生的数据。
* 组项:具有从属数据项的数据项称为组项,例如,学生的姓名由名字和姓氏组成。
* 记录:记录可以定义为各种数据项的集合,例如,如果以学生实体为例,那么学生的名称,地址,课程和标记可以组合在一起形成学生的记录。
* 文件文件是一种类型实体的各种记录的集合例如如果类中有60名员工则相关文件中将有20条记录其中每条记录包含有关每个员工的数据。
* 属性和实体:实体表示某些对象的类。它包含各种属性。每个属性表示该实体的特定属性。
* 字段:字段是表示实体属性的单个基本信息单元。
### 为什么需要数据结构
随着应用程序变得越来越复杂,数据量日益增加,可能会出现以下问题:
* 处理器速度:要处理非常大的数据,需要高速处理,但随着数据逐日增长到每个实体数十亿个文件,处理器可能无法处理大量数据。
* 数据搜索假设商店的库存大小是100860个商品如果应用程序需要搜索某一特定商品则每次需要遍历100860个商品这会导致搜索过程变慢。
* 大量请求如果成千上万的用户在Web服务器上同时搜索数据在此过程中可能在短时会有一个非常大请求而导致服务器处理不了。
### 数据结构的优点
* 效率:程序的效率取决于数据结构的选择。
* 可重用性:数据结构是可重用的,即当实现了特定的数据结构,就可以在其他地方使用它。也将数据结构的实现编译到不同客户端使用的程序库中
* 抽象数据结构由ADT指定它提供抽象级别。 客户端程序仅通过接口使用数据结构,而不涉及实现细节。
## 2 数据结构分类
![](2021-03-12-17-07-01.png)
### 线性数据结构
如果数据结构的所有元素按线性顺序排列,则称为线性数据结构。 在线性数据结构中,元素以非分层方式存储,除了第一个和最后一个元素,它的每个元素具有后继元素和前导元素。
线性数据结构的类型如下:
* 数组:数组是类似数据项的集合,每个数据项称为数组的元素。 元素的数据类型可以是任何有效的数据类型如charintfloat或double。数组的元素共享相同的变量名但每个元素都带有一个不同的索引号这些索引号也称为下标。 数组可以是一维的,二维的或多维的。
```
age[0], age[1], age[2], age[3],.... age[98], age[99]
```
* 链表:链表是一种线性数据结构,用于维护内存中的列表。 它可以看作存储在非连续内存位置的节点集合。链表中的每个节点都包含指向其相邻节点的指针。
* 堆栈 :堆栈是一个线性列表,其中只允许在一端插入和删除,称为顶部。堆栈是一种抽象数据类型(ADT),可以在大多数编程语言中实现。 它被命名为堆栈,因为它的行为类似于真实世界的堆栈,例如:成堆的板块或卡片组等,只能在最顶面上操作。
* 队列:队列是一个线性列表,它的元素只能在一端插入(添加),也被称为后端,而只在另一端出队(删除),也被称为前端。
### 非线性数据结构
非线性数据结构不形成序列,即每个项目或元素以非线性排列与两个或更多个其他项目连接。 数据元素不按顺序结构排列。
非线性数据结构的类型如下:
* 树:树是多级数据结构,其元素之间具有层次关系,树的元素也称为节点。层次中最底层的节点称为叶节点,而最顶层节点称为根节点。 每个节点都包含指向相邻节点的指针。树数据结构基于节点之间的父子关系。 除了叶节点之外,树中的每个节点可以具有多个子节点,而除了根节点之外,每个节点可以具有最多一个父节点。 树可以分为许多类别,本教程在稍后章节中将对此进行讨论。
* 图:图可以定义为由称为边缘的链接连接的元素集(由顶点表示)的图表示。 图不同于树,图可以有循环而树不能具有循环。
## 3 数据结构的操作
> 从数据结构的角度
* 遍历:每个数据结构都包含一组数据元素。遍历数据结构表示访问数据结构的每个元素,以便执行某些特定操作,如搜索或排序。示例 如果需要计算学生在6个不同科目中获得的分数的平均值需要遍历完整的分数数组并计算总和然后将总分数除以科目数即6 最后得到平均值。
* 插入插入是在任何位置将元素添加到数据结构的过程。如果数据结构的大小是n那么只能在n-1个数据元素之间插入元素。
* 删除:从数据结构中删除元素的过程称为删除。 可以在任何随机位置删除数据结构中的元素。如果要从空数据结构中删除元素,则会发生下溢。
* 搜索:在数据结构中查找元素位置的过程称为搜索。 有两种算法可以执行搜索,即线性搜索和二进制搜索。在本教程后面讨论这两种搜索算法。
* 排序:按特定顺序排列数据结构的过程称为排序。 有许多算法可用于执行排序,例如,插入排序,选择排序,冒泡排序等。
* 更新:为更新数据结构中的现有元素而开发的算法。
* 合并当两个列表分别为大小为M和N的列表A和列表B时相似类型的元素连接产生第三个列表列表C的大小(M + N),则此过程称为合并。

169
数据结构/1 数组.md Normal file
View File

@@ -0,0 +1,169 @@
# 数组
## 1 数组的简介
### 定义
* 数组是存储在**连续内存位置**的**相同类型数据项**的集合,是最简单的**线性数据结构**。
* 数组的每个数据元素都可以使用下表索引运算符,进行**随机访问**。
* 数组可以有一个或**多个维度**。
* 每个元素具有**相同的数据类型**并且具有相同的大小即int = 4个字节。
```
int arr[10];
char arr[10];
float arr[5];
```
### 优点
* 数组为同一类型的变量组提供单一名称,因此很容易记住数组中所有元素的名称。
* 遍历数组是一个非常简单的过程,只需要递增数组的基址,就可以逐个访问每个元素。
* 可以使用索引直接访问数组中的任何元素。
### 时间复杂性
| 算法 | 平均情况 | 最坏情况 |
|----|------|------|
| 访问 | O(1) | O(1) |
| 搜索 | O(n) | O(n) |
| 插入 | O(n) | O(n) |
| 删除 | O(n) | O(n) |
### 空间复杂性
* 在数组中最坏情况下的空间复杂度是O(n)。
## 2 数组的类型
### 一维数组
* 一维(或单维)数组是一种线性数组,其中元素的访问是以行或列索引的单一下标表示。
* C++ 将高维维数组存储为一维数组。因此,如果我们将 A 定义为也包含 M * N 个元素的二维数组,那么实际上 A[i][j] 就等于 A[i * N + j]。
### 多维数组
* 普通数组采用一个整数来作下标。多维数组(高维数组)的概念特别是在数值计算和图形应用方面非常有用。我们在多维数组之中采用一系列有序的整数来标注,如在[ 3,1,5 ] 。这种整数列表之中整数的个数始终相同,且被称为数组的“维度”。关于每个数组维度的边界称为“维”。维度为 k 的数组通常被称为 k 维。
* 多维数组的数组名字,在表达式中自动转换为数组首元素地址值,但这个首元素实际上是去除数组下标第一维之后的数组剩余部分。
## 3 数组的存储和实现
### 数组存储
* 数组的所有数据元素都存储在主存储器中的连续位置。
* 数组名称表示主存储器中的基地址或第一个元素的地址。
* 数组的每个元素都由适当的索引表示。可以用三种方式定义数组的索引。
* 0(从零开始索引)数组的第一个元素是arr[0]。
* 1(基于一个索引)数组的第一个元素是arr [1]。
* n(基于n的索引):基于数组的第一个元素,可以定位任何随机索引值。
![](2021-03-12-20-47-17.png)
### 数组实现
* C++内置数组数据类型。
```
int a[4];
double b[3][9];//内置数组
```
* STL提供两种灵活的数组结构。
```
array<int, 5> arr = {1, 2, 3, 4, 5};//STL模板数组
vector<int> vec ={3,4,3};//STL模板向量可变长度的数组
```
## 4 数组的操作
### 基础操作
* 创建
* 遍历
* 插入
* 删除
### 创建
```
// 定义数组
int size =20;//容量
int numbers =10;//数据量
int a[20]={1,3,4,5,6,7,4,2,4,5};
```
### 遍历
```C++
// 数组遍历
for(int i=0;i<10;i++){
cout<<a[i];
}
```
### 插入
```C++
//数组插入,尾插入
int value=9;
if(numbers<size){
a[numbers]=value;
numbers++;
}
else{
cout<<"overflow"<<endl;
}
// 数组插入,头插入
int value=10;
if(numbers<size){
for(int i=1;i<=numbers,i++){
a[numbers]=a[numbers-i];
}
a[0]=value;
}
else{
cout<<"overflow"<<endl;
}
```
### 删除
```C++
// 删除
int aim=8;
if(aim>=numbers){
cout<<"overbound"<<endl;
}
else{
for(int i=aim;i<numbers-1;i++){
a[i]=a[i+1];
}
}
```
## 5 二维数组(矩阵)
### 二维数组的表示
* 二维数组的大小等于行数和数组中存在的列数的乘积。
* 一般将二维数组映射到一维数组,存储在内存中。
* 一个3 X 3的二维数组如下图所示。需要将此数组映射到一维数组存储到内存中。
![](2021-03-12-20-55-32.png)
### 二维数组的存储——行主顺序
* 在行主排序中,二维数组的所有行连续地存储在存储器中。上图中所示数组,它按行主顺序的存储器分配如下所示
![](2021-03-12-20-57-19.png)
![](2021-03-12-20-58-14.png)
### 二维数组的存储——列主顺序
* 根据列主排序,二维数组的所有列都连续地存储在存储器中。 上面图像中所示数组的存储器分配给出如下
![](2021-03-12-20-57-51.png)
![](2021-03-12-20-58-23.png)
### 计算二维数组随机元素的地址
* 由于存在两种不同的将二维数组存储到存储器中的技术,因此也有两种不同的公式来计算二维数组的随机元素的地址。
* 按行主顺序如果数组由a[m][n]声明其中m是行数而n是列数则以行主顺序存储的数组的元素a[i][j]的地址计算为
```
Address(a[i][j]) = B. A. + (i * n + j) * size
```
* 按列主顺序如果数组由a[m][n]声明其中m是行数而n是列数则以列主顺序存储的数组的元素a[i][j]的地址计算为,
```
Address(a[i][j]) = ((j*m)+i)*Size + BA
```

47
数据结构/1.cpp Normal file
View File

@@ -0,0 +1,47 @@
#include<iostream>
using namespace std;
int main(){
// 定义数组
int size =20;//容量
int numbers =10;//数据量
int a[20]={1,3,4,5,6,7,4,2,4,5};
// 数组遍历
for(int i=0;i<10;i++){
cout<<a[i];
}
//数组插入,尾插入
int value=9;
if(numbers<size){
a[numbers]=value;
numbers++;
}
else{
cout<<"overflow"<<endl;
}
// 数组插入,头插入
int value2=10;
if(numbers<size){
for(int i=1;i<=numbers;i++){
a[numbers]=a[numbers-i];
}
a[0]=value2;
}
else{
cout<<"overflow"<<endl;
}
// 删除
int aim=8;
if(aim>=numbers){
cout<<"overbound"<<endl;
}
else{
for(int i=aim;i<numbers-1;i++){
a[i]=a[i+1];
}
}
}

41
数据结构/2 链表.md Normal file
View File

@@ -0,0 +1,41 @@
# 链表
## 1 简介
### 链表概念
* 链表是一种随机存储在内存中的节点对象集合。
* 节点包含两个字段,即存储在该地址的数据和包含下一个节点地址的指针。
* 链表的最后一个节点包含指向null的指针。
![](2021-03-12-21-00-33.png)
![](2021-03-12-21-01-53.png)
### 链表特点
* 链表不需要连续存在于存储器中。节点可以是存储器中的任何位置并链接在一起以形成链表。这实现了空间的优化利用。
* 链表大小仅限于内存大小,不需要提前声明。
* 空节点不能出现在链表中。
* 在单链表中存储基元类型或对象的值。
### 链表与数组的对比
* 数组有以下限制:
* 在程序中使用数组之前,必须事先知道数组的大小。
* 增加数组的大小是一个耗时的过程。在运行时几乎不可能扩展数组的大小。
* 数组中的所有元素都需要连续存储在内存中。在数组中插入任何元素都需要移动元素之前所有的数据。
* 链表是可以克服数组所有限制的数据结构。 链表是非常有用的,因为,
* 它动态分配内存。链表的所有节点都是非连续存储在存储器中,并使用指针链接在一起。
* 大小调整不再是问题,因为不需要在声明时定义大小。链表根据程序的需求增长,并且仅限于可用的内存空间。
## 2 链表的类型
### 分类
* 单链表
* 双链表
* 循环单链表
* 循环双链表

View File

@@ -0,0 +1,341 @@
# 单链表
## 1 简介
### 概念
* 单链表是有序元素集的集合。元素的数量可以根据程序的需要而变化。 单链表中的节点由两部分组成:数据部分和链接部分。
* 节点的数据部分存储将由节点表示的实际信息,而节点的链接部分存储其直接后继的地址。
* 单向链或单链表可以仅在一个方向上遍历。也就是说每个节点只包含下一个节点的指针,因此不能反向遍历链表。
![](2021-03-12-21-00-33.png)
![](2021-03-12-21-08-07.png)
### 链表复杂度
| 操作 | 平均复杂度 | 最坏复杂度 |
|----|-------|-------|
| 访问 | θ(n) | θ(n) |
| 搜索 | θ(n) | θ(n) |
| 插入 | θ(1) | θ(1) |
| 删除 | θ(1) | θ(1) |
## 2 链表的存储和实现
### 链表的存储
* 链表不需要连续存在于存储器中。节点可以是存储器中的任何位置并链接在一起以形成链表。这实现了空间的优化利用。
### 链表的实现
* 链表通过结构体和指针实现
```C++
struct node
{
int data;
struct node *next;
};
struct node *head, *ptr;
ptr = (struct node *)malloc(sizeof(struct node *));
```
* C++ STL提供了链表的实现
```
#include<list>
list<int> li;
forward_list<int> li;
```
## 3 链表的操作
### 基本操作
* 创建
* 遍历、搜索、查找(同一类操作)
* 插入(尾插入、头插入、中间插入)
* 删除
### 实现
```C++
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *head;
void beginsert();
void lastinsert();
void randominsert();
void begin_delete();
void last_delete();
void random_delete();
void display();
void search();
int main()
{
int choice = 0;
while (choice != 9)
{
printf("\n\n********* 主菜单 *********\n");
printf("从以下菜单列表中选择一个选项操作 ...\n");
printf("===============================================\n");
printf("1.插入到开头\n");
printf("2.插入到结尾\n");
printf("3.插入任何随机位置\n");
printf("4.从头部删除\n");
printf("5.从尾部删除\n");
printf("6.删除指定位置后的节点\n");
printf("7.搜索元素\n");
printf("8.显示链表中的数据\n");
printf("9.退出\n\n");
printf("===============================================\n");
printf("请输入您的选择:");
scanf("%d", &choice);
switch (choice)
{
case 1:
beginsert();
break;
case 2:
lastinsert();
break;
case 3:
randominsert();
break;
case 4:
begin_delete();
break;
case 5:
last_delete();
break;
case 6:
random_delete();
break;
case 7:
search();
break;
case 8:
display();
break;
case 9:
exit(0);
break;
default:
printf("请输入有效的选项...");
}
}
return 0;
}
void beginsert()
{
struct node *ptr;
int item;
ptr = (struct node *) malloc(sizeof(struct node *));
if (ptr == NULL)
{
printf("内存不够!\n");
}
else
{
printf("请输入一个整数值:");
scanf("%d", &item);
ptr->data = item;
ptr->next = head;
head = ptr;
printf("节点已经成功插入\n");
}
}
void lastinsert()
{
struct node *ptr, *temp;
int item;
ptr = (struct node*)malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("内存不够!\n");
}
else
{
printf("请输入一个整数值:");
scanf("%d", &item);
ptr->data = item;
if (head == NULL)
{
ptr->next = NULL;
head = ptr;
printf("节点已经成功插入\n");
}
else
{
temp = head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = ptr;
ptr->next = NULL;
printf("节点已经成功插入\n");
}
}
}
void randominsert()
{
int i, loc, item;
struct node *ptr, *temp;
ptr = (struct node *) malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("内存不够!\n");
}
else
{
printf("请输入一个整数值:");
scanf("%d", &item);
ptr->data = item;
printf("输入要插入的位置:");
scanf("%d", &loc);
temp = head;
for (i = 0;i < loc;i++)
{
temp = temp->next;
if (temp == NULL)
{
printf("此处不能插入节点\n");
return;
}
}
ptr->next = temp->next;
temp->next = ptr;
printf("节点已经成功插入\n");
}
}
void begin_delete()
{
struct node *ptr;
if (head == NULL)
{
printf("链表为空,没有什么可以删除!\n");
}
else
{
ptr = head;
head = ptr->next;
free(ptr);
printf("已经删除头部节点 ...\n");
}
}
void last_delete()
{
struct node *ptr, *ptr1;
if (head == NULL)
{
printf("链表为空,没有什么可以删除!\n");
}
else if (head->next == NULL)
{
head = NULL;
free(head);
printf("唯一的节点已经被删除了...\n");
}
else
{
ptr = head;
while (ptr->next != NULL)
{
ptr1 = ptr;
ptr = ptr->next;
}
ptr1->next = NULL;
free(ptr);
printf("已删除最后一个节点...\n");
}
}
void random_delete()
{
struct node *ptr, *ptr1;
int loc, i;
printf("输入要在此节点之后执行删除的节点的位置:");
scanf("%d", &loc);
ptr = head;
for (i = 0;i < loc;i++)
{
ptr1 = ptr;
ptr = ptr->next;
if (ptr == NULL)
{
printf("不能删除\n");
return;
}
}
ptr1->next = ptr->next;
free(ptr);
printf("\n第 %d 个节点已经被删除了", loc + 1);
}
void search()
{
struct node *ptr;
int item, i = 0, flag;
ptr = head;
if (ptr == NULL)
{
printf("链表为空!\n");
}
else
{
printf("请输入要搜索的项目:");
scanf("%d", &item);
while (ptr != NULL)
{
if (ptr->data == item)
{
printf("在 %d 位置找到数据项\n", i + 1);
flag = 0;
}
else
{
flag = 1;
}
i++;
ptr = ptr->next;
}
if (flag == 1)
{
printf("数据项未找到\n");
}
}
}
/**
* 显示链表中的数据
*/
void display()
{
struct node *ptr;
ptr = head;
if (ptr == NULL)
{
printf("链表为空,没有数据可以显示。");
}
else
{
printf("链表中的数据值如下所示:\n");
printf("--------------------------------------------------\n");
while (ptr != NULL)
{
printf("\n%d", ptr->data);
ptr = ptr->next;
}
}
printf("\n\n\n");
}
```

282
数据结构/2.1.cpp Normal file
View File

@@ -0,0 +1,282 @@
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *head;
void beginsert();
void lastinsert();
void randominsert();
void begin_delete();
void last_delete();
void random_delete();
void display();
void search();
int main()
{
int choice = 0;
while (choice != 9)
{
printf("\n\n********* 主菜单 *********\n");
printf("从以下菜单列表中选择一个选项操作 ...\n");
printf("===============================================\n");
printf("1.插入到开头\n");
printf("2.插入到结尾\n");
printf("3.插入任何随机位置\n");
printf("4.从头部删除\n");
printf("5.从尾部删除\n");
printf("6.删除指定位置后的节点\n");
printf("7.搜索元素\n");
printf("8.显示链表中的数据\n");
printf("9.退出\n\n");
printf("===============================================\n");
printf("请输入您的选择:");
scanf("%d", &choice);
switch (choice)
{
case 1:
beginsert();
break;
case 2:
lastinsert();
break;
case 3:
randominsert();
break;
case 4:
begin_delete();
break;
case 5:
last_delete();
break;
case 6:
random_delete();
break;
case 7:
search();
break;
case 8:
display();
break;
case 9:
exit(0);
break;
default:
printf("请输入有效的选项...");
}
}
return 0;
}
void beginsert()
{
struct node *ptr;
int item;
ptr = (struct node *) malloc(sizeof(struct node *));
if (ptr == NULL)
{
printf("内存不够!\n");
}
else
{
printf("请输入一个整数值:");
scanf("%d", &item);
ptr->data = item;
ptr->next = head;
head = ptr;
printf("节点已经成功插入\n");
}
}
void lastinsert()
{
struct node *ptr, *temp;
int item;
ptr = (struct node*)malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("内存不够!\n");
}
else
{
printf("请输入一个整数值:");
scanf("%d", &item);
ptr->data = item;
if (head == NULL)
{
ptr->next = NULL;
head = ptr;
printf("节点已经成功插入\n");
}
else
{
temp = head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = ptr;
ptr->next = NULL;
printf("节点已经成功插入\n");
}
}
}
void randominsert()
{
int i, loc, item;
struct node *ptr, *temp;
ptr = (struct node *) malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("内存不够!\n");
}
else
{
printf("请输入一个整数值:");
scanf("%d", &item);
ptr->data = item;
printf("输入要插入的位置:");
scanf("%d", &loc);
temp = head;
for (i = 0;i < loc;i++)
{
temp = temp->next;
if (temp == NULL)
{
printf("此处不能插入节点\n");
return;
}
}
ptr->next = temp->next;
temp->next = ptr;
printf("节点已经成功插入\n");
}
}
void begin_delete()
{
struct node *ptr;
if (head == NULL)
{
printf("链表为空,没有什么可以删除!\n");
}
else
{
ptr = head;
head = ptr->next;
free(ptr);
printf("已经删除头部节点 ...\n");
}
}
void last_delete()
{
struct node *ptr, *ptr1;
if (head == NULL)
{
printf("链表为空,没有什么可以删除!\n");
}
else if (head->next == NULL)
{
head = NULL;
free(head);
printf("唯一的节点已经被删除了...\n");
}
else
{
ptr = head;
while (ptr->next != NULL)
{
ptr1 = ptr;
ptr = ptr->next;
}
ptr1->next = NULL;
free(ptr);
printf("已删除最后一个节点...\n");
}
}
void random_delete()
{
struct node *ptr, *ptr1;
int loc, i;
printf("输入要在此节点之后执行删除的节点的位置:");
scanf("%d", &loc);
ptr = head;
for (i = 0;i < loc;i++)
{
ptr1 = ptr;
ptr = ptr->next;
if (ptr == NULL)
{
printf("不能删除\n");
return;
}
}
ptr1->next = ptr->next;
free(ptr);
printf("\n第 %d 个节点已经被删除了", loc + 1);
}
void search()
{
struct node *ptr;
int item, i = 0, flag;
ptr = head;
if (ptr == NULL)
{
printf("链表为空!\n");
}
else
{
printf("请输入要搜索的项目:");
scanf("%d", &item);
while (ptr != NULL)
{
if (ptr->data == item)
{
printf("在 %d 位置找到数据项\n", i + 1);
flag = 0;
}
else
{
flag = 1;
}
i++;
ptr = ptr->next;
}
if (flag == 1)
{
printf("数据项未找到\n");
}
}
}
/**
* 显示链表中的数据
*/
void display()
{
struct node *ptr;
ptr = head;
if (ptr == NULL)
{
printf("链表为空,没有数据可以显示。");
}
else
{
printf("链表中的数据值如下所示:\n");
printf("--------------------------------------------------\n");
while (ptr != NULL)
{
printf("\n%d", ptr->data);
ptr = ptr->next;
}
}
printf("\n\n\n");
}

View File

@@ -0,0 +1,329 @@
# 双链表
## 1 双链表的简介
### 概念
* 双向链表是一种复杂类型的链表,它的节点包含指向序列中前一个节点和下一个节点的指针。
* 在双向链表中,节点由三部分组成:节点数据,指向下一个节点的指针(next指针),指向前一个节点的指针(prev指针)。
![](2021-03-12-21-14-57.png)
![](2021-03-12-21-14-50.png)
## 2 双链表的存储和实现
### 数据存储
* 双向链表为每个节点消耗更多空间
* 可以更灵活地操作链表中的元素。
![](双链表的数据存储.png)
### 数据实现
* 使用结构体和指针实现。
```C
struct node
{
struct node *prev;
int data;
struct node *next;
}
```
* 使用STL中的list实现
```
#include<list>
list<int> li;
```
## 3 双链表的操作
### 基本操作
* 创建
* 遍历、搜索
* 插入
* 删除
### 实现
```C++
#include<stdio.h>
#include<stdlib.h>
struct node
{
struct node *prev;
struct node *next;
int data;
};
struct node *head;
void insertion_beginning();
void insertion_last();
void insertion_specified();
void deletion_beginning();
void deletion_last();
void deletion_specified();
void display();
void search();
void main()
{
int choice = 0;
while (choice != 9)
{
printf("*********Main Menu*********\n");
printf("Choose one option from the following list ...\n");
printf("===============================================\n");
printf("1.Insert in begining\n2.Insert at last\n3.Insert at any random location\n4.Delete from Beginning\n5.Delete from last\n6.Delete the node after the given data\n7.Search\n8.Show\n9.Exit\n");
printf("Enter your choice?\n");
scanf("%d", &choice);
switch (choice)
{
case 1:
insertion_beginning();
break;
case 2:
insertion_last();
break;
case 3:
insertion_specified();
break;
case 4:
deletion_beginning();
break;
case 5:
deletion_last();
break;
case 6:
deletion_specified();
break;
case 7:
search();
break;
case 8:
display();
break;
case 9:
exit(0);
break;
default:
printf("Please enter valid choice..");
}
}
}
void insertion_beginning()
{
struct node *ptr;
int item;
ptr = (struct node *)malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("OVERFLOW\n");
}
else
{
printf("Enter Item value");
scanf("%d", &item);
if (head == NULL)
{
ptr->next = NULL;
ptr->prev = NULL;
ptr->data = item;
head = ptr;
}
else
{
ptr->data = item;
ptr->prev = NULL;
ptr->next = head;
head->prev = ptr;
head = ptr;
}
printf("Node inserted\n");
}
}
void insertion_last()
{
struct node *ptr, *temp;
int item;
ptr = (struct node *) malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("OVERFLOW\n");
}
else
{
printf("Enter value");
scanf("%d", &item);
ptr->data = item;
if (head == NULL)
{
ptr->next = NULL;
ptr->prev = NULL;
head = ptr;
}
else
{
temp = head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = ptr;
ptr->prev = temp;
ptr->next = NULL;
}
}
printf("node inserted\n");
}
void insertion_specified()
{
struct node *ptr, *temp;
int item, loc, i;
ptr = (struct node *)malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("OVERFLOW\n");
}
else
{
temp = head;
printf("Enter the location ");
scanf("%d", &loc);
for (i = 0;i < loc;i++)
{
temp = temp->next;
if (temp == NULL)
{
printf("There are less than %d elements", loc);
return;
}
}
printf("Enter value");
scanf("%d", &item);
ptr->data = item;
ptr->next = temp->next;
ptr->prev = temp;
temp->next = ptr;
temp->next->prev = ptr;
printf("node inserted\n");
}
}
void deletion_beginning()
{
struct node *ptr;
if (head == NULL)
{
printf("UNDERFLOW\n");
}
else if (head->next == NULL)
{
head = NULL;
free(head);
printf("node deleted\n");
}
else
{
ptr = head;
head = head->next;
head->prev = NULL;
free(ptr);
printf("node deleted\n");
}
}
void deletion_last()
{
struct node *ptr;
if (head == NULL)
{
printf("UNDERFLOW\n");
}
else if (head->next == NULL)
{
head = NULL;
free(head);
printf("node deleted\n");
}
else
{
ptr = head;
if (ptr->next != NULL)
{
ptr = ptr->next;
}
ptr->prev->next = NULL;
free(ptr);
printf("node deleted\n");
}
}
void deletion_specified()
{
struct node *ptr, *temp;
int val;
printf("Enter the data after which the node is to be deleted : ");
scanf("%d", &val);
ptr = head;
while (ptr->data != val)
ptr = ptr->next;
if (ptr->next == NULL)
{
printf("Can't delete\n");
}
else if (ptr->next->next == NULL)
{
ptr->next = NULL;
}
else
{
temp = ptr->next;
ptr->next = temp->next;
temp->next->prev = ptr;
free(temp);
printf("node deleted\n");
}
}
void display()
{
struct node *ptr;
printf("printing values...\n");
ptr = head;
while (ptr != NULL)
{
printf("%d\n", ptr->data);
ptr = ptr->next;
}
}
void search()
{
struct node *ptr;
int item, i = 0, flag;
ptr = head;
if (ptr == NULL)
{
printf("Empty List\n");
}
else
{
printf("Enter item which you want to search?\n");
scanf("%d", &item);
while (ptr != NULL)
{
if (ptr->data == item)
{
printf("item found at location %d ", i + 1);
flag = 0;
break;
}
else
{
flag = 1;
}
i++;
ptr = ptr->next;
}
if (flag == 1)
{
printf("Item not found\n");
}
}
}
```

283
数据结构/2.2.cpp Normal file
View File

@@ -0,0 +1,283 @@
#include<stdio.h>
#include<stdlib.h>
struct node
{
struct node *prev;
struct node *next;
int data;
};
struct node *head;
void insertion_beginning();
void insertion_last();
void insertion_specified();
void deletion_beginning();
void deletion_last();
void deletion_specified();
void display();
void search();
void main()
{
int choice = 0;
while (choice != 9)
{
printf("*********Main Menu*********\n");
printf("Choose one option from the following list ...\n");
printf("===============================================\n");
printf("1.Insert in begining\n2.Insert at last\n3.Insert at any random location\n4.Delete from Beginning\n5.Delete from last\n6.Delete the node after the given data\n7.Search\n8.Show\n9.Exit\n");
printf("Enter your choice?\n");
scanf("%d", &choice);
switch (choice)
{
case 1:
insertion_beginning();
break;
case 2:
insertion_last();
break;
case 3:
insertion_specified();
break;
case 4:
deletion_beginning();
break;
case 5:
deletion_last();
break;
case 6:
deletion_specified();
break;
case 7:
search();
break;
case 8:
display();
break;
case 9:
exit(0);
break;
default:
printf("Please enter valid choice..");
}
}
}
void insertion_beginning()
{
struct node *ptr;
int item;
ptr = (struct node *)malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("OVERFLOW\n");
}
else
{
printf("Enter Item value");
scanf("%d", &item);
if (head == NULL)
{
ptr->next = NULL;
ptr->prev = NULL;
ptr->data = item;
head = ptr;
}
else
{
ptr->data = item;
ptr->prev = NULL;
ptr->next = head;
head->prev = ptr;
head = ptr;
}
printf("Node inserted\n");
}
}
void insertion_last()
{
struct node *ptr, *temp;
int item;
ptr = (struct node *) malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("OVERFLOW\n");
}
else
{
printf("Enter value");
scanf("%d", &item);
ptr->data = item;
if (head == NULL)
{
ptr->next = NULL;
ptr->prev = NULL;
head = ptr;
}
else
{
temp = head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = ptr;
ptr->prev = temp;
ptr->next = NULL;
}
}
printf("node inserted\n");
}
void insertion_specified()
{
struct node *ptr, *temp;
int item, loc, i;
ptr = (struct node *)malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("OVERFLOW\n");
}
else
{
temp = head;
printf("Enter the location ");
scanf("%d", &loc);
for (i = 0;i < loc;i++)
{
temp = temp->next;
if (temp == NULL)
{
printf("There are less than %d elements", loc);
return;
}
}
printf("Enter value");
scanf("%d", &item);
ptr->data = item;
ptr->next = temp->next;
ptr->prev = temp;
temp->next = ptr;
temp->next->prev = ptr;
printf("node inserted\n");
}
}
void deletion_beginning()
{
struct node *ptr;
if (head == NULL)
{
printf("UNDERFLOW\n");
}
else if (head->next == NULL)
{
head = NULL;
free(head);
printf("node deleted\n");
}
else
{
ptr = head;
head = head->next;
head->prev = NULL;
free(ptr);
printf("node deleted\n");
}
}
void deletion_last()
{
struct node *ptr;
if (head == NULL)
{
printf("UNDERFLOW\n");
}
else if (head->next == NULL)
{
head = NULL;
free(head);
printf("node deleted\n");
}
else
{
ptr = head;
if (ptr->next != NULL)
{
ptr = ptr->next;
}
ptr->prev->next = NULL;
free(ptr);
printf("node deleted\n");
}
}
void deletion_specified()
{
struct node *ptr, *temp;
int val;
printf("Enter the data after which the node is to be deleted : ");
scanf("%d", &val);
ptr = head;
while (ptr->data != val)
ptr = ptr->next;
if (ptr->next == NULL)
{
printf("Can't delete\n");
}
else if (ptr->next->next == NULL)
{
ptr->next = NULL;
}
else
{
temp = ptr->next;
ptr->next = temp->next;
temp->next->prev = ptr;
free(temp);
printf("node deleted\n");
}
}
void display()
{
struct node *ptr;
printf("printing values...\n");
ptr = head;
while (ptr != NULL)
{
printf("%d\n", ptr->data);
ptr = ptr->next;
}
}
void search()
{
struct node *ptr;
int item, i = 0, flag;
ptr = head;
if (ptr == NULL)
{
printf("Empty List\n");
}
else
{
printf("Enter item which you want to search?\n");
scanf("%d", &item);
while (ptr != NULL)
{
if (ptr->data == item)
{
printf("item found at location %d ", i + 1);
flag = 0;
break;
}
else
{
flag = 1;
}
i++;
ptr = ptr->next;
}
if (flag == 1)
{
printf("Item not found\n");
}
}
}

View File

@@ -0,0 +1,297 @@
# 循环单向链表
## 1 简介
### 概念
* 在循环单链表中,链表的最后一个节点包含指向链表的第一个节点的指针。可以有循环单向链表以及循环双链表。
* 遍历一个循环单链表直到到达开始的同一个节点。循环单链表类似于链表但它没有开始也没有结束。任何节点的下一部分都不存在NULL值。
![](循环单向链表.png)
## 2 数据存储和实现
### 数据存储
链表的最后一个节点包含链表的第一个节点的地址。
![](2021-03-12-21-21-07.png)
### 数据实现
* 链表通过结构体和指针实现
```C++
struct node
{
int data;
struct node *next;
};
struct node *head, *ptr;
ptr = (struct node *)malloc(sizeof(struct node *));
```
* C++ STL提供了链表的实现
```
#include<list>
list<int> li;
forward_list<int> li;
```
## 3 操作
### 基本操作
* 创建
* 遍历、搜索
* 插入
* 删除
### 实现
```C++
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *head;
void beginsert();
void lastinsert();
void randominsert();
void begin_delete();
void last_delete();
void random_delete();
void display();
void search();
int main()
{
int choice = 0;
while (choice != 7)
{
printf("*********Main Menu*********\n");
printf("Choose one option from the following list ...\n");
printf("===============================================\n");
printf("1.Insert in begining\n2.Insert at last\n");
printf("3.Delete from Beginning\n4.Delete from last\n");
printf("5.Search for an element\n6.Show\n7.Exit\n");
printf("Enter your choice?\n");
scanf("%d", &choice);
switch (choice)
{
case 1:
beginsert();
break;
case 2:
lastinsert();
break;
case 3:
begin_delete();
break;
case 4:
last_delete();
break;
case 5:
search();
break;
case 6:
display();
break;
case 7:
exit(0);
break;
default:
printf("Please enter valid choice..");
}
}
}
void beginsert()
{
struct node *ptr, *temp;
int item;
ptr = (struct node *)malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("OVERFLOW");
}
else
{
printf("Enter the node data?");
scanf("%d", &item);
ptr->data = item;
if (head == NULL)
{
head = ptr;
ptr->next = head;
}
else
{
temp = head;
while (temp->next != head)
temp = temp->next;
ptr->next = head;
temp->next = ptr;
head = ptr;
}
printf("node inserted\n");
}
}
void lastinsert()
{
struct node *ptr, *temp;
int item;
ptr = (struct node *)malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("OVERFLOW\n");
}
else
{
printf("Enter Data?");
scanf("%d", &item);
ptr->data = item;
if (head == NULL)
{
head = ptr;
ptr->next = head;
}
else
{
temp = head;
while (temp->next != head)
{
temp = temp->next;
}
temp->next = ptr;
ptr->next = head;
}
printf("node inserted\n");
}
}
void begin_delete()
{
struct node *ptr;
if (head == NULL)
{
printf("UNDERFLOW");
}
else if (head->next == head)
{
head = NULL;
free(head);
printf("node deleted\n");
}
else
{
ptr = head;
while (ptr->next != head)
ptr = ptr->next;
ptr->next = head->next;
free(head);
head = ptr->next;
printf("node deleted\n");
}
}
void last_delete()
{
struct node *ptr, *preptr;
if (head == NULL)
{
printf("UNDERFLOW");
}
else if (head->next == head)
{
head = NULL;
free(head);
printf("node deleted\n");
}
else
{
ptr = head;
while (ptr->next != head)
{
preptr = ptr;
ptr = ptr->next;
}
preptr->next = ptr->next;
free(ptr);
printf("node deleted\n");
}
}
void search()
{
struct node *ptr;
int item, i = 0, flag = 1;
ptr = head;
if (ptr == NULL)
{
printf("Empty List\n");
}
else
{
printf("Enter item which you want to search?\n");
scanf("%d", &item);
if (head->data == item)
{
printf("item found at location %d", i + 1);
flag = 0;
}
else
{
while (ptr->next != head)
{
if (ptr->data == item)
{
printf("item found at location %d ", i + 1);
flag = 0;
break;
}
else
{
flag = 1;
}
i++;
ptr = ptr->next;
}
}
if (flag != 0)
{
printf("Item not found\n");
}
}
}
void display()
{
struct node *ptr;
ptr = head;
if (head == NULL)
{
printf("nothing to print");
}
else
{
printf("printing values ... \n");
while (ptr->next != head)
{
printf("%d\n", ptr->data);
ptr = ptr->next;
}
printf("%d\n", ptr->data);
}
}
```

246
数据结构/2.3.cpp Normal file
View File

@@ -0,0 +1,246 @@
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *head;
void beginsert();
void lastinsert();
void randominsert();
void begin_delete();
void last_delete();
void random_delete();
void display();
void search();
int main()
{
int choice = 0;
while (choice != 7)
{
printf("*********Main Menu*********\n");
printf("Choose one option from the following list ...\n");
printf("===============================================\n");
printf("1.Insert in begining\n2.Insert at last\n");
printf("3.Delete from Beginning\n4.Delete from last\n");
printf("5.Search for an element\n6.Show\n7.Exit\n");
printf("Enter your choice?\n");
scanf("%d", &choice);
switch (choice)
{
case 1:
beginsert();
break;
case 2:
lastinsert();
break;
case 3:
begin_delete();
break;
case 4:
last_delete();
break;
case 5:
search();
break;
case 6:
display();
break;
case 7:
exit(0);
break;
default:
printf("Please enter valid choice..");
}
}
}
void beginsert()
{
struct node *ptr, *temp;
int item;
ptr = (struct node *)malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("OVERFLOW");
}
else
{
printf("Enter the node data?");
scanf("%d", &item);
ptr->data = item;
if (head == NULL)
{
head = ptr;
ptr->next = head;
}
else
{
temp = head;
while (temp->next != head)
temp = temp->next;
ptr->next = head;
temp->next = ptr;
head = ptr;
}
printf("node inserted\n");
}
}
void lastinsert()
{
struct node *ptr, *temp;
int item;
ptr = (struct node *)malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("OVERFLOW\n");
}
else
{
printf("Enter Data?");
scanf("%d", &item);
ptr->data = item;
if (head == NULL)
{
head = ptr;
ptr->next = head;
}
else
{
temp = head;
while (temp->next != head)
{
temp = temp->next;
}
temp->next = ptr;
ptr->next = head;
}
printf("node inserted\n");
}
}
void begin_delete()
{
struct node *ptr;
if (head == NULL)
{
printf("UNDERFLOW");
}
else if (head->next == head)
{
head = NULL;
free(head);
printf("node deleted\n");
}
else
{
ptr = head;
while (ptr->next != head)
ptr = ptr->next;
ptr->next = head->next;
free(head);
head = ptr->next;
printf("node deleted\n");
}
}
void last_delete()
{
struct node *ptr, *preptr;
if (head == NULL)
{
printf("UNDERFLOW");
}
else if (head->next == head)
{
head = NULL;
free(head);
printf("node deleted\n");
}
else
{
ptr = head;
while (ptr->next != head)
{
preptr = ptr;
ptr = ptr->next;
}
preptr->next = ptr->next;
free(ptr);
printf("node deleted\n");
}
}
void search()
{
struct node *ptr;
int item, i = 0, flag = 1;
ptr = head;
if (ptr == NULL)
{
printf("Empty List\n");
}
else
{
printf("Enter item which you want to search?\n");
scanf("%d", &item);
if (head->data == item)
{
printf("item found at location %d", i + 1);
flag = 0;
}
else
{
while (ptr->next != head)
{
if (ptr->data == item)
{
printf("item found at location %d ", i + 1);
flag = 0;
break;
}
else
{
flag = 1;
}
i++;
ptr = ptr->next;
}
}
if (flag != 0)
{
printf("Item not found\n");
}
}
}
void display()
{
struct node *ptr;
ptr = head;
if (head == NULL)
{
printf("nothing to print");
}
else
{
printf("printing values ... \n");
while (ptr->next != head)
{
printf("%d\n", ptr->data);
ptr = ptr->next;
}
printf("%d\n", ptr->data);
}
}

View File

@@ -0,0 +1,298 @@
# 循环双向链表
## 1 简介
### 概念
* 循环双向链表是一种更复杂的数据结构类型,它的节点包含指向其前一节点以及下一节点的指针。
* 循环双向链表在任何节点中都不包含NULL。
* 链表的最后一个节点包含列表的第一个节点的地址。
* 链表的第一个节点还包含的前一个指针是指向最后一个节点的地址。
![](2021-03-12-21-22-43.png)
## 2 数据存储和实现
### 数据存储
* 起始节点包含最后一个(也是前一个)节点的地址即8和下一个节点即4。链表的最后一个节点存储在地址8并包含数据6包含链表的第一个节点的地址
![](循环双向链表内存.png)
### 数据实现
* 使用结构体和指针实现。
```C
struct node
{
struct node *prev;
int data;
struct node *next;
}
```
* 使用STL中的list实现
```
#include<list>
list<int> li;
```
## 3 操作
### 基本操作
* 创建
* 遍历、搜索
* 插入
* 删除
### 实现
```
#include<stdio.h>
#include<stdlib.h>
struct node
{
struct node *prev;
struct node *next;
int data;
};
struct node *head;
void insertion_beginning();
void insertion_last();
void deletion_beginning();
void deletion_last();
void display();
void search();
int main()
{
int choice = 0;
while (choice != 9)
{
printf("*********Main Menu*********\n");
printf("Choose one option from the following list ...\n");
printf("===============================================\n");
printf("1.Insert in Beginning\n2.Insert at last\n");
printf("3.Delete from Beginning\n4.Delete from last\n");
printf("5.Search\n6.Show\n7.Exit\n");
printf("Enter your choice?\n");
scanf("\n%d", &choice);
switch (choice)
{
case 1:
insertion_beginning();
break;
case 2:
insertion_last();
break;
case 3:
deletion_beginning();
break;
case 4:
deletion_last();
break;
case 5:
search();
break;
case 6:
display();
break;
case 7:
exit(0);
break;
default:
printf("Please enter valid choice..");
}
}
}
void insertion_beginning()
{
struct node *ptr, *temp;
int item;
ptr = (struct node *)malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("OVERFLOW");
}
else
{
printf("Enter Item value");
scanf("%d", &item);
ptr->data = item;
if (head == NULL)
{
head = ptr;
ptr->next = head;
ptr->prev = head;
}
else
{
temp = head;
while (temp->next != head)
{
temp = temp->next;
}
temp->next = ptr;
ptr->prev = temp;
head->prev = ptr;
ptr->next = head;
head = ptr;
}
printf("Node inserted\n");
}
}
void insertion_last()
{
struct node *ptr, *temp;
int item;
ptr = (struct node *) malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("OVERFLOW");
}
else
{
printf("Enter value");
scanf("%d", &item);
ptr->data = item;
if (head == NULL)
{
head = ptr;
ptr->next = head;
ptr->prev = head;
}
else
{
temp = head;
while (temp->next != head)
{
temp = temp->next;
}
temp->next = ptr;
ptr->prev = temp;
head->prev = ptr;
ptr->next = head;
}
}
printf("node inserted\n");
}
void deletion_beginning()
{
struct node *temp;
if (head == NULL)
{
printf("UNDERFLOW");
}
else if (head->next == head)
{
head = NULL;
free(head);
printf("node deleted\n");
}
else
{
temp = head;
while (temp->next != head)
{
temp = temp->next;
}
temp->next = head->next;
head->next->prev = temp;
free(head);
head = temp->next;
}
}
void deletion_last()
{
struct node *ptr;
if (head == NULL)
{
printf("UNDERFLOW");
}
else if (head->next == head)
{
head = NULL;
free(head);
printf("node deleted\n");
}
else
{
ptr = head;
if (ptr->next != head)
{
ptr = ptr->next;
}
ptr->prev->next = head;
head->prev = ptr->prev;
free(ptr);
printf("node deleted\n");
}
}
void display()
{
struct node *ptr;
ptr = head;
if (head == NULL)
{
printf("nothing to print");
}
else
{
printf("printing values ... \n");
while (ptr->next != head)
{
printf("%d\n", ptr->data);
ptr = ptr->next;
}
printf("%d\n", ptr->data);
}
}
void search()
{
struct node *ptr;
int item, i = 0, flag = 1;
ptr = head;
if (ptr == NULL)
{
printf("Empty List\n");
}
else
{
printf("Enter item which you want to search?\n");
scanf("%d", &item);
if (head->data == item)
{
printf("item found at location %d", i + 1);
flag = 0;
}
else
{
while (ptr->next != head)
{
if (ptr->data == item)
{
printf("item found at location %d ", i + 1);
flag = 0;
break;
}
else
{
flag = 1;
}
i++;
ptr = ptr->next;
}
}
if (flag != 0)
{
printf("Item not found\n");
}
}
}
```

249
数据结构/2.4.cpp Normal file
View File

@@ -0,0 +1,249 @@
#include<stdio.h>
#include<stdlib.h>
struct node
{
struct node *prev;
struct node *next;
int data;
};
struct node *head;
void insertion_beginning();
void insertion_last();
void deletion_beginning();
void deletion_last();
void display();
void search();
int main()
{
int choice = 0;
while (choice != 9)
{
printf("*********Main Menu*********\n");
printf("Choose one option from the following list ...\n");
printf("===============================================\n");
printf("1.Insert in Beginning\n2.Insert at last\n");
printf("3.Delete from Beginning\n4.Delete from last\n");
printf("5.Search\n6.Show\n7.Exit\n");
printf("Enter your choice?\n");
scanf("\n%d", &choice);
switch (choice)
{
case 1:
insertion_beginning();
break;
case 2:
insertion_last();
break;
case 3:
deletion_beginning();
break;
case 4:
deletion_last();
break;
case 5:
search();
break;
case 6:
display();
break;
case 7:
exit(0);
break;
default:
printf("Please enter valid choice..");
}
}
}
void insertion_beginning()
{
struct node *ptr, *temp;
int item;
ptr = (struct node *)malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("OVERFLOW");
}
else
{
printf("Enter Item value");
scanf("%d", &item);
ptr->data = item;
if (head == NULL)
{
head = ptr;
ptr->next = head;
ptr->prev = head;
}
else
{
temp = head;
while (temp->next != head)
{
temp = temp->next;
}
temp->next = ptr;
ptr->prev = temp;
head->prev = ptr;
ptr->next = head;
head = ptr;
}
printf("Node inserted\n");
}
}
void insertion_last()
{
struct node *ptr, *temp;
int item;
ptr = (struct node *) malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("OVERFLOW");
}
else
{
printf("Enter value");
scanf("%d", &item);
ptr->data = item;
if (head == NULL)
{
head = ptr;
ptr->next = head;
ptr->prev = head;
}
else
{
temp = head;
while (temp->next != head)
{
temp = temp->next;
}
temp->next = ptr;
ptr->prev = temp;
head->prev = ptr;
ptr->next = head;
}
}
printf("node inserted\n");
}
void deletion_beginning()
{
struct node *temp;
if (head == NULL)
{
printf("UNDERFLOW");
}
else if (head->next == head)
{
head = NULL;
free(head);
printf("node deleted\n");
}
else
{
temp = head;
while (temp->next != head)
{
temp = temp->next;
}
temp->next = head->next;
head->next->prev = temp;
free(head);
head = temp->next;
}
}
void deletion_last()
{
struct node *ptr;
if (head == NULL)
{
printf("UNDERFLOW");
}
else if (head->next == head)
{
head = NULL;
free(head);
printf("node deleted\n");
}
else
{
ptr = head;
if (ptr->next != head)
{
ptr = ptr->next;
}
ptr->prev->next = head;
head->prev = ptr->prev;
free(ptr);
printf("node deleted\n");
}
}
void display()
{
struct node *ptr;
ptr = head;
if (head == NULL)
{
printf("nothing to print");
}
else
{
printf("printing values ... \n");
while (ptr->next != head)
{
printf("%d\n", ptr->data);
ptr = ptr->next;
}
printf("%d\n", ptr->data);
}
}
void search()
{
struct node *ptr;
int item, i = 0, flag = 1;
ptr = head;
if (ptr == NULL)
{
printf("Empty List\n");
}
else
{
printf("Enter item which you want to search?\n");
scanf("%d", &item);
if (head->data == item)
{
printf("item found at location %d", i + 1);
flag = 0;
}
else
{
while (ptr->next != head)
{
if (ptr->data == item)
{
printf("item found at location %d ", i + 1);
flag = 0;
break;
}
else
{
flag = 1;
}
i++;
ptr = ptr->next;
}
}
if (flag != 0)
{
printf("Item not found\n");
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

255
数据结构/3 栈.md Normal file
View File

@@ -0,0 +1,255 @@
# 堆栈
## 1 简介
### 概念
* 堆栈stack又称为栈是计算机科学中一种特殊的串列形式的抽象数据类型
* 堆栈(Stack)是一个有序列表,它只能在顶端执行插入和删除。
* 堆栈(Stack)是一个递归数据结构,具有指向其顶部元素的指针。
* 堆栈为后进先出(LIFO)列表,即首先插入堆栈的元素将最后从堆栈中删除.
![](堆栈.png)
### 应用
* 深度优先搜索与回溯
* 递归
* 表达式评估和转换
* 解析
* 浏览器
* 编辑器
* 树遍历
### 特点
1. 先入后出,后入先出。
2. 除头尾节点之外,每个元素有一个前驱,一个后继。
## 2 栈的操作
### 基础操作
- 推入 push
- 将数据放入堆栈的顶端(数组形式或串列形式),堆栈顶端 top 指针加一。
![](2021-03-12-21-29-39.png)
- 弹出 pop
- 将顶端数据数据输出(回传),堆栈顶端数据减一。
![](2021-03-12-21-29-49.png)
- 查看 top
- 查看栈顶的元素而不删除它们。
> 以后有时间来实现这些数据结构
## 3 栈的实现
### 数组实现
```C++
#include <stdio.h>
int stack[100], i, j, choice = 0, n, top = -1;
void push();
void pop();
void show();
void main()
{
printf("Enter the number of elements in the stack ");
scanf("%d", &n);
printf("*********Stack operations using array*********");
printf("----------------------------------------------\n");
while (choice != 4)
{
printf("Chose one from the below options...\n");
printf("1.Push\n2.Pop\n3.Show\n4.Exit");
printf("Enter your choice \n");
scanf("%d", &choice);
switch (choice)
{
case 1:
{
push();
break;
}
case 2:
{
pop();
break;
}
case 3:
{
show();
break;
}
case 4:
{
printf("Exiting....");
break;
}
default:
{
printf("Please Enter valid choice ");
}
};
}
}
void push()
{
int val;
if (top == n)
printf("Overflow");
else
{
printf("Enter the value?");
scanf("%d", &val);
top = top + 1;
stack[top] = val;
}
}
void pop()
{
if (top == -1)
printf("Underflow");
else
top = top - 1;
}
void show()
{
for (i = top;i >= 0;i--)
{
printf("%d\n", stack[i]);
}
if (top == -1)
{
printf("Stack is empty");
}
}
```
### 链表实现
```C++
#include <stdio.h>
#include <stdlib.h>
void push();
void pop();
void display();
struct node
{
int val;
struct node *next;
};
struct node *head;
void main()
{
int choice = 0;
printf("*********Stack operations using linked list*********\n");
printf("----------------------------------------------\n");
while (choice != 4)
{
printf("Chose one from the below options...\n");
printf("1.Push\n2.Pop\n3.Show\n4.Exit");
printf("Enter your choice \n");
scanf("%d", &choice);
switch (choice)
{
case 1:
{
push();
break;
}
case 2:
{
pop();
break;
}
case 3:
{
display();
break;
}
case 4:
{
printf("Exiting....");
break;
}
default:
{
printf("Please Enter valid choice ");
}
};
}
}
void push()
{
int val;
struct node *ptr = (struct node*)malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("not able to push the element");
}
else
{
printf("Enter the value");
scanf("%d", &val);
if (head == NULL)
{
ptr->val = val;
ptr->next = NULL;
head = ptr;
}
else
{
ptr->val = val;
ptr->next = head;
head = ptr;
}
printf("Item pushed");
}
}
void pop()
{
int item;
struct node *ptr;
if (head == NULL)
{
printf("Underflow");
}
else
{
item = head->val;
ptr = head;
head = head->next;
free(ptr);
printf("Item popped");
}
}
void display()
{
int i;
struct node *ptr;
ptr = head;
if (ptr == NULL)
{
printf("Stack is empty\n");
}
else
{
printf("Printing Stack elements \n");
while (ptr != NULL)
{
printf("%d\n", ptr->val);
ptr = ptr->next;
}
}
}
```

259
数据结构/4 队列.md Normal file
View File

@@ -0,0 +1,259 @@
# 队列
## 1 简介
### 概念
* 队列可以定义为有序列表。在一端执行插入操作rear删除操作在另一端执行称为front。
* 队列被称为先进先出列表。
![](2021-03-12-21-36-39.png)
### 应用
* 单个共享资源(如打印机磁盘CPU)的等待列表。
* 异步数据传输。管道文件IO套接字。
* 缓冲区.
* 操作系统中处理中断。
### 时间复杂度
| 时间复杂性 | 访问 | 搜索 | 插入 | 删除 |
|-------|------|------|------|------|
| 平均情况 | θ(n) | θ(n) | θ(1) | θ(1) |
| 最坏情况 | θ(n) | θ(n) | θ(1) | θ(1) |
## 2 队列的操作
### 基本操作
* 创建
* 遍历(显示第一个元素)
* 插入
* 删除
## 3 队列的实现
### 队列的数组实现
```C++
#include<stdio.h>
#include<stdlib.h>
#define maxsize 5
void insert();
void delete();
void display();
int front = -1, rear = -1;
int queue[maxsize];
void main()
{
int choice;
while (choice != 4)
{
printf("*************************Main Menu*****************************\n");
printf("=================================================================\n");
printf("1.insert an element\n2.Delete an element\n3.Display the queue\n4.Exit\n");
printf("Enter your choice ?");
scanf("%d", &choice);
switch (choice)
{
case 1:
insert();
break;
case 2:
delete();
break;
case 3:
display();
break;
case 4:
exit(0);
break;
default:
printf("Enter valid choice??\n");
}
}
}
void insert()
{
int item;
printf("\nEnter the element\n");
scanf("\n%d", &item);
if (rear == maxsize - 1)
{
printf("OVERFLOW\n");
return;
}
if (front == -1 && rear == -1)
{
front = 0;
rear = 0;
}
else
{
rear = rear + 1;
}
queue[rear] = item;
printf("Value inserted ");
}
void delete()
{
int item;
if (front == -1 || front > rear)
{
printf("UNDERFLOW\n");
return;
}
else
{
item = queue[front];
if (front == rear)
{
front = -1;
rear = -1;
}
else
{
front = front + 1;
}
printf("value deleted ");
}
}
void display()
{
int i;
if (rear == -1)
{
printf("Empty queue\n");
}
else
{
printf("printing values .....\n");
for (i = front;i <= rear;i++)
{
printf("\n%d\n", queue[i]);
}
}
}
```
### 队列的链表实现
```C++
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *front;
struct node *rear;
void insert();
void delete();
void display();
void main()
{
int choice;
while (choice != 4)
{
printf("*************************Main Menu*****************************\n");
printf("=================================================================\n");
printf("1.insert an element\n2.Delete an element\n3.Display the queue\n4.Exit\n");
printf("Enter your choice ?");
scanf("%d", &choice);
switch (choice)
{
case 1:
insert();
break;
case 2:
delete();
break;
case 3:
display();
break;
case 4:
exit(0);
break;
default:
printf("Enter valid choice??\n");
}
}
}
void insert()
{
struct node *ptr;
int item;
ptr = (struct node *) malloc(sizeof(struct node));
if (ptr == NULL)
{
printf("OVERFLOW\n");
return;
}
else
{
printf("Enter value?\n");
scanf("%d", &item);
ptr->data = item;
if (front == NULL)
{
front = ptr;
rear = ptr;
front->next = NULL;
rear->next = NULL;
}
else
{
rear->next = ptr;
rear = ptr;
rear->next = NULL;
}
}
}
void delete ()
{
struct node *ptr;
if (front == NULL)
{
printf("UNDERFLOW\n");
return;
}
else
{
ptr = front;
front = front->next;
free(ptr);
}
}
void display()
{
struct node *ptr;
ptr = front;
if (front == NULL)
{
printf("Empty queue\n");
}
else
{
printf("printing values .....\n");
while (ptr != NULL)
{
printf("%d\n", ptr->data);
ptr = ptr->next;
}
}
}
```
### C++模板
```
#include<queue>
queue<int> que;
```

Some files were not shown because too many files have changed in this diff Show More