├── 22 DS ├── 22级DS第1次作业.md ├── 22级DS第2次作业.md ├── 22级DS第3次作业.md ├── 22级DS第4次作业.md ├── 22级DS第5次作业.md ├── Archive │ ├── 22级DS第1次作业.pdf │ ├── 22级DS第2次作业.pdf │ ├── 22级DS第3次作业.pdf │ └── 22级DS第4次作业.pdf ├── Dev_cpp 配置 │ ├── README.md │ └── themes │ │ ├── Dracula.syntax │ │ ├── Intellij-Dark.syntax │ │ ├── Intellij-Light.syntax │ │ ├── Monokai.syntax │ │ ├── Pink.syntax │ │ ├── README.md │ │ ├── Sakura.syntax │ │ ├── Vector.syntax │ │ ├── copy.bat │ │ └── one-dark-pro.syntax ├── README.md ├── Ref │ ├── .DS+bug全扫除计划.pdf │ ├── ASCII.JPG │ ├── Priority.JPG │ ├── T1.pdf │ ├── T2.pdf │ ├── T3-链表.pdf │ ├── T4-栈与队.pdf │ ├── ctype.h.JPG │ ├── return_val.PNG │ ├── stdio.h.JPG │ ├── stdlib.h.JPG │ └── string.h.JPG ├── Simtool_debug │ ├── README.md │ ├── README.pdf │ ├── comparator.cpp │ └── simtool_debug.exe ├── Templates │ ├── README.md │ ├── list.c │ ├── qsort.c │ ├── queue.c │ └── stack.c ├── assets │ ├── image-20230404173011756.png │ └── image-20230404175707391.png └── 期中复刻? │ └── T2 │ ├── check.py │ ├── gen.py │ └── std.c └── README.MD /22 DS/22级DS第1次作业.md: -------------------------------------------------------------------------------- 1 | # 22级DS第一次作业 2 | 3 | > $Author : \mathcal{Red}$ 4 | > 5 | > 若有疑问,欢迎联系 ProjektRed@buaa.edu.cn 6 | 7 | ## 选择题 8 | 9 | 1. 执行 `strcpy(a, b)` 后 `a[]` 的内容为 `{'A', 'B', 'C', '\0', 'd', 'e', 'f', '\0'}`,`a[1] == B`,故输出为 `B`。 10 | 11 | 2. A. 不能通过`=`给字符数组整体赋值,即不能将字符串常量或另一个数组赋值给字符数组。 12 | 13 | B. 定义时可以将字符串常量初始化给字符数组,`[]` 代表按最小能满足需要的空间自动分配数组大小。 14 | 15 | C、D. 字符串常量 `"abcdefghijklmn"` 的长度$+ 1 >$ 字符数组大小,溢出。 16 | 17 | 3. 空字符 `'\0'` 是字符串的结束标志,`strlen` 函数会在遇到它之后停止计数,故返回值为 `'\0'` 前的元素个数 $3$。附 `c[]` 的内容:`{'\t', '\v', '\\', '\0', 'w', 'i', 'l', 'l', '\n', '\0'}`(我不确定是否所有编译器的都会为 `c[]` 分配 $10$ 字节的空间) 18 | 19 | 4. 不能通过`=`给字符数组整体赋值 20 | 21 | 5. A. `strlen("ABCDE")+1`大于字符数组大小,溢出,无空间分配给 `'\0'` 22 | 23 | B. 未写入 `'\0'` 24 | 25 | C. 字符指针指向常量字符串,结尾一定为 `'\0'`。 26 | 27 | D. 字符指针未初始化,未分配空间,此时的读入为未定义行为。 28 | 29 | 6. 还是 不能通过`=`给字符数组整体赋值。 30 | 31 | 7. 递归执行可得 $\text{try}(n)=\prod\limits_{i=0}^{\lceil\frac n2\rceil-1}(n-2i)=n!!$。 32 | 33 | 8. 不知道怎么写解析,自己想。 34 | 35 | 9. `language` 是一个包含 $5$ 个指向常量字符串的指针的字符指针数组。 36 | 37 | A. `language + 2` 为 `language` 数组第三个元素的地址,`*(language + 2)` 即为 `language[2]`,为指向 `"PASCAL"` 的指针。 38 | 39 | B. 同上可得。 40 | 41 | C. 已解释 42 | 43 | D. `language` 的每个元素是指针而不是数组。 44 | 45 | 10. 令 $k$ 为循环执行次数,则结束后 $x=2^{k+1}$,有 $\dfrac n2\le2^{k+1}\le n$,即 $\log_2n-1\le k+1\le\log_2n$,故 $k=\text{O}(\log_2n)$ 46 | 47 | ## 填空题 48 | 49 | 5. `main` 函数声明错误()。`func` 函数修改的是传入的形参而非其指向内容,故无法完成对实参的修改,错误,可将参数改为 `char **q` ,传入 `&p`并修改 `*q`。 50 | 51 | 感觉没啥好写的,摸了 -------------------------------------------------------------------------------- /22 DS/22级DS第2次作业.md: -------------------------------------------------------------------------------- 1 | # DS第二次作业 2 | 3 | > 根据21级题目内容编写,如有不同请指出 4 | > 5 | > $Author : \mathcal{Red}$ 6 | > 7 | > 若有疑问,欢迎联系 ProjektRed@buaa.edu.cn 8 | 9 | ## 选择题 10 | 11 | 1. `[]` 优先级高于 `*`,故 `*q[5]` 等价于 `*(q[5])`(优先级可见附录)。 12 | 13 | 2. `int (* ptr) [M]` 中 `ptr` 先与 `*` 结合,故其为指针,然后指针与 `[M]`结合,变为指向 M 大小数组的指针。 14 | 15 | 3. `*(p1++)` 等价于 `*p1`,即 `*(x+2)` $=$ `x[2]`。 16 | 17 | 4. 好麻烦。 18 | 19 | A、C. 指针数组的每一项均应为指针 20 | 21 | D. `num` 为数组指针,应指向大小为 $4$ 的 `int` 数组 22 | 23 | 5. 非字符串类型输入时写至地址,输出时提供值。`p` 为等于 `a` 的地址的指针,不应当作为 `%d` 输出。 24 | 25 | 6. 参考函数原型:`int fprintf(FILE *stream, const char *format, ...)`。 26 | 27 | 7. `void f(struct stu)`函数不改变实参,`s[0]`仍为初始值。 28 | 29 | 8. A. `*pt->y`$=$`*(pt->y)`$=$`*(c[0].y)` 30 | 31 | B. `pt->x`$=$`c[0].x` 32 | 33 | C. `++pt->x`$=$`++(pt->x)` 34 | 35 | D. `(pt++)->x` 相当于 `pt->x` 36 | 37 | 9. `typedef` 为结构体取别名 `OLD`,合法。`struct node` 与 `OLD` 为结构类型,仅结构体名在`c`语言中不能作为结构类型。 38 | 39 | 10. 和上面差不多,掌握好前后自增的区别,需要时查询优先级表即可。 40 | 41 | 11. 嵌套结构体,一层一层调用即可。 42 | 43 | 12. 还是和上面差不多。 44 | 45 | 13. D 中 `stduent` 为该结构体别名,而不是结构体名,应使用 `student std1;` 46 | 47 | 14. 不是 `typedef`,`var` 为结构体变量而非类型名。 48 | 49 | 15. `*` 优先级低于 `.`,D 项等价于 `*(p.age)` 50 | 51 | ## 填空题 52 | 53 | 感觉没什么好分析的,有疑问直接提出,我做补充。 54 | 55 | 4. 等号表达式会返回被赋值后的等号左侧内容。如以下代码 56 | 57 | ```c 58 | #include 59 | int main() 60 | { 61 | int a; 62 | double b, int_return_val, double_return_val; 63 | int_return_val = (a = 2.5); 64 | double_return_val = (b = 2.5); 65 | printf("%d %.2lf %.2f %.2f", a, b, int_return_val, double_return_val); 66 | } 67 | ``` 68 | 69 | 输出结果为 `2 2.50 2.00 2.50`。 70 | 71 | ## 附录 72 | 73 | ![优先级](C:\Users\85990\Documents\Codefield\Code_C\C_Single\Reference\优先级.JPG) -------------------------------------------------------------------------------- /22 DS/22级DS第3次作业.md: -------------------------------------------------------------------------------- 1 | # 22级DS第三次作业 2 | 3 | > $Author : \mathcal{Red}$ 4 | > 5 | > 若有疑问,欢迎联系 ProjektRed@buaa.edu.cn 6 | 7 | ## 选择 8 | 9 | 1. 单项链表,仅需修改前驱节点的后继与新节点的后继。为循环链表,故不需要考虑尾节点特殊性。 10 | 2. 循环链表中链尾节点的后继为头节点;`p` 指针指向链尾节点,即其为链尾节点的指针。 11 | 3. 有序性指元素顺序不同即为不同对象,而不是指元素有序。 12 | 4. 外层循环执行次数满足 $2^{cnt_k-1}\le n< 2^{cnt_k}$,即 $\log_2n $Author : \mathcal{Red}$ 4 | > 5 | > 若有疑问,欢迎联系 ProjektRed@buaa.edu.cn 6 | 7 | ## 选择 8 | 9 | 1. 分清顺序/链式存储与线性/非线性结构: 10 | 11 | - 存储:顺序存储为顺序表(数组),链式存储为链表; 12 | - 线性结构:元素有序(有前后关系)即为线性结构,否则为非线性。 13 | 14 | 2. 从递归调用思考,使用的参数为调用该函数时传入的,也就是最新传入的,而在使用后参数也将从结构中删除;返回地址也是类似,但返回的实际原理大家可能并不了解,可以不考虑这方面,在学 CO 课程时会有更深刻的理解。所以考虑实现上述需求需要什么数据结构。 15 | 16 | 3. 队列先入先出,对顺序没用影响,统计任意时刻栈内元素个数最大值即可。 17 | 18 | 4. 可以实际模拟一下试试能不能实现。 19 | 20 | > 一些速通技巧:在单个栈的出栈队列中,假设入栈队列为 $1,2,3,\dots,n$,那么在某个数出现后,找到其后所有比它小的数,得到的序列一定是单减的,否则不合法。 21 | > 22 | > 如 $4\ 3\ 1\ 2\ 5$ 中,$4$ 后面所有比它小的数的序列为 $3\ 1\ 2$,不为单调减,不合法 23 | > 24 | > $1\ 4\ 3\ 5\ 7\ 6\ 2$ 中,$1$ 后无,$2$ 后无,$3$ 后为 $2$,$4$ 后为 $3\ 2$,$5$ 后为 $2$,$6$ 后为 $2$,$7$ 后为 $6\ 2$,均为单减,故合法(操作串为 SXSSSXXSXSSXXX) 25 | 26 | 5. 类似上题。 27 | 28 | 6. 根据规则转换~不多说了。 29 | 30 | 7. 修改 p 的两个指针与插入左右节点需要改动的一侧的指针。 31 | 32 | 8. 顺序存储结构可能会满。 33 | 34 | 9. 先进先出。 35 | 36 | 10. 第一个元素进入队列后,`front` 为队头元素 $0$,`rear` 为队尾元素也为 $0$,则倒推一下,即可得到初始状态的 `front` 与 `rear`。 37 | 38 | 11. 喵~ 39 | 40 | 12. T3 弱化版。 41 | 42 | 13. 队列为在队尾添加元素,在队头删除元素。 43 | 44 | - 出队(删除元素):`front` 后移; 45 | - 入队(增加元素):`rear` 后移。 46 | 47 | ## 填空 48 | 49 | 5. 本题的后缀表达式各元素中间不需要空格(黏在一起也没事,很神奇吧)。 50 | 51 | 52 | 7. 填 $M$ 与 $M-1$ 均正确。 53 | - $M-1$:不维护额外信息的循环队列只能容纳 $M-1$ 个元素,否则有 $M$ 个元素时,$front = rear$,无法区分空与满; 54 | - $M$:仅需维护是否为空即可。 55 | 56 | ## 编程 Hint 57 | 58 | ### BRACKET 59 | 60 | 可以把自己的代码作为一个样例,以下为另一些易错的样例。 61 | 62 | #### TESTCASE #1 63 | 64 | ``` 65 | /***/()*/ 66 | ``` 67 | 68 | ### CALCULATER 69 | 70 | 按照规则转后缀表达式,然后计算。 71 | 72 | 转换方式可参考: 73 | 74 | image-20230404175707391 75 | 76 | ### EDIT 77 | 78 | 插入操作保证插入后 插入字符串 的 第一个字符 位于 pos 处 79 | 80 | ### 臭名昭著的BANK 81 | 82 | 感谢image-20230404173011756的总结 83 | 84 | 一周期内进行的操作 85 | 86 | 1. 加入本周期内所有新的顾客到队列 87 | 88 | 2. **当且仅当**有新的顾客到队列(第一步执行),检查是否需要增加窗口 89 | 90 | 3. 空闲且激活的窗口和窗口的顾客已经服务完成的,从队列弹出顾客进入窗口服务 91 | 92 | 4. 窗口服务顾客(窗口服务顾客指的是**所有有顾客的窗口**,包括不被激活但是有顾客的窗口) 93 | 94 | > $\color{red}{\text{Red}}$ 注:如果有人进服务了,就会一直处于服务中状态,也即是现在当前窗口数不影响当前服务中的人,而当且仅当当前服务人数少于当前窗口数时有窗口可以服务新人 95 | 96 | 5. 队列中的顾客等待 97 | 98 | 6. 检查是否需要减少窗口(只需要看减少前的平均等待人数是否小于7,不需要考虑减少后平均等待人数是否小于7,也就是说不管怎么样**只要平均人数少于7就减少窗口**) 99 | 100 | 7. 周期结束 101 | 102 | #### 伪代码 103 | 104 | ```c 105 | while (round <= n || !queue_empty()) { 106 | if (round <= n) { 107 | add_customer(); 108 | increase_window(); 109 | } 110 | serve(); // 服务所有处在服务中状态的顾客 111 | decrease_window(); // 只要当前平均人数小于7就减少窗口 112 | round++; 113 | } 114 | ``` 115 | 116 | -------------------------------------------------------------------------------- /22 DS/22级DS第5次作业.md: -------------------------------------------------------------------------------- 1 | # 22级DS第五次作业 2 | 3 | > $Author : \mathcal{Red}$ 4 | > 5 | > 若有疑问,欢迎联系 ProjektRed@buaa.edu.cn 6 | 7 | ## 选择 8 | 9 | 咕咕咕 10 | 11 | ## 填空 12 | 13 | 咕咕咕 14 | 15 | ## 编程 Hint 16 | 17 | 咕咕咕 18 | 19 | ## 实验 20 | 21 | 咕咕咕 22 | -------------------------------------------------------------------------------- /22 DS/Archive/22级DS第1次作业.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/Archive/22级DS第1次作业.pdf -------------------------------------------------------------------------------- /22 DS/Archive/22级DS第2次作业.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/Archive/22级DS第2次作业.pdf -------------------------------------------------------------------------------- /22 DS/Archive/22级DS第3次作业.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/Archive/22级DS第3次作业.pdf -------------------------------------------------------------------------------- /22 DS/Archive/22级DS第4次作业.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/Archive/22级DS第4次作业.pdf -------------------------------------------------------------------------------- /22 DS/Dev_cpp 配置/README.md: -------------------------------------------------------------------------------- 1 | # 不用 Dev_cpp 2 | 3 | > $Author : \mathcal{Red}$ 4 | > 5 | 6 | 推荐使用 Clion(配置较简单但软件较大,吃内存)或 vscode(轻量级,但可能需要一定的配置能力)。 7 | 8 | 如果你一定想用 Dev_cpp 或是不想配置其他编辑器,以下为一些让它变得稍微能用一些的方法: 9 | 10 | - 编译选项: 11 | 12 | 设置中修改你正在使用的编译器配置(Release 或 Debug 那个) 13 | 14 | - 在”编译器“,部分勾选“编译时加入以下命令”并在其中加入 `-fexec-charset=GBK` 以使其更好地支持中文输出 15 | - 在”代码生成/优化“部分: 16 | - C 编译器:选择支持所有 ANSI C 标准 17 | - 代码生成:语言标准选择较高的 ISO C 标准,如 C99 18 | - 代码警告:显示最多警告信息 19 | 20 | - 环境选项-浏览 Debug 变量-查看鼠标指向的变量(不确定有没有用) 21 | 22 | - 编辑器选项: 23 | 24 | - ~~不选使用 tab 字符~~ 25 | - 可在语法中选择一个自己喜欢的主题,在 theme 文件夹下也有一些推荐的可用主题与使用方法,更换深色主题建议同时更换基本-高亮显示当前行的颜色或直接将其关闭 26 | - 代码补全-CodeCompletion 里全勾上,延迟可以随便调低一点,然后前往设置-快捷键选项,翻到最下面倒数第三个,将快捷键更改为一个与系统快捷键不冲突的选项,然后 dev_c 就也有(很难用的)代码补全啦 27 | 28 | Dev_cpp 可能还有一些你所不知道的功能,比如 `Ctrl+Shift+A` 可以自动格式化,`Ctrl+Click` 可以跳转至库函数声明 -------------------------------------------------------------------------------- /22 DS/Dev_cpp 配置/themes/Dracula.syntax: -------------------------------------------------------------------------------- 1 | [Editor.Custom] 2 | Assembler=$00C679FF, $00362A28, 0, 0, 0 3 | Character=$008CFAF1, $00362A28, 0, 0, 0 4 | Comment=$00A47262, $00362A28, 0, 0, 0 5 | Float=$FFF993BE, $00362A28, 0, 0, 0 6 | Hexadecimal=$00F993BD, $00362A28, 0, 0, 0 7 | Identifier=$00F2F8F8, $00362A28, 0, 0, 0 8 | Illegal Char=$005555FF, $00362A28, 0, 0, 0 9 | Number=$00F993BD, $00362A28, 0, 0, 0 10 | Octal=$00F993BD, $00362A28, 0, 0, 0 11 | Preprocessor=$00C679FF, $00362A28, 0, 0, 0 12 | Reserved Word=$00FDE98B, $00362A28, 0, 1, 0 13 | Space=clWindowText, $00362A28, 0, 0, 0 14 | String=$008BE9FC, clNone, 0, 0, 0 15 | Symbol=$00C679FF, $00362A28, 0, 0, 0 16 | Selected text=15923448, 5916484 17 | Gutter=10777186, 3549736 18 | Breakpoints=15923448, 13007359 19 | Error line=16777215, 5592564 20 | Active breakpoints=16777215, 16356285 21 | Folding lines=5916484, 5328448 -------------------------------------------------------------------------------- /22 DS/Dev_cpp 配置/themes/Intellij-Dark.syntax: -------------------------------------------------------------------------------- 1 | [Editor.Custom] 2 | Assembler=clBlack, $002B2B2B, 0, 0, 0 3 | Character=$00517A61, $002B2B2B, 0, 0, 0 4 | Comment=clGray, $002B2B2B, 0, 1, 0 5 | Float=$00FF6633, $002B2B2B, 0, 0, 0 6 | Hexadecimal=$00FF6633, $002B2B2B, 0, 0, 0 7 | Identifier=$00BCAEA1, $002B2B2B, 0, 0, 0 8 | Illegal Char=$00517A61, $002B2B2B, 0, 0, 0 9 | Number=$00FF6633, $002B2B2B, 0, 0, 0 10 | Octal=$00FF6633, $002B2B2B, 0, 0, 0 11 | Preprocessor=$003278CC, $002B2B2B, 0, 0, 0 12 | Reserved Word=$003278CC, $002B2B2B, 0, 0, 0 13 | Space=clWhite, $002B2B2B, 0, 0, 0 14 | String=$00517A61, $002B2B2B, 0, 0, 0 15 | Symbol=$00BCAEA1, $002B2B2B, 0, 0, 0 16 | Selected text=12365473, 8602145 17 | Gutter=5592405, 2829099 18 | Breakpoints=12365473, 2302798 19 | Error line=16777215, 128 20 | Active breakpoints=12365473, 2302778 21 | Folding lines=12365473, -16777201 22 | -------------------------------------------------------------------------------- /22 DS/Dev_cpp 配置/themes/Intellij-Light.syntax: -------------------------------------------------------------------------------- 1 | [Editor.Custom] 2 | Assembler=clBlack, $002B2B2B, 0, 0, 0 3 | Character=$00517A61, $002B2B2B, 0, 0, 0 4 | Comment=$00CCA59D, clWhite, 0, 1, 0 5 | Float=$00FF6633, clWhite, 0, 0, 0 6 | Hexadecimal=$00FF6633, clWhite, 0, 0, 0 7 | Identifier=$00080808, clWhite, 0, 0, 0 8 | Illegal Char=$00517A61, clWhite, 0, 0, 0 9 | Number=$00B3350A, clWhite, 0, 0, 0 10 | Octal=$00B3350A, clWhite, 0, 0, 0 11 | Preprocessor=$00B3350A, clWhite, 0, 0, 0 12 | Reserved Word=$00B3350A, clWhite, 0, 0, 0 13 | Space=clWhite, clWhite, 0, 0, 0 14 | String=$00517A61, clWhite, 0, 0, 0 15 | Symbol=$00080808, clWhite, 0, 0, 0 16 | Selected text=526344, 16765606 17 | Gutter=13948116, 15921906 18 | Breakpoints=526344, 15199231 19 | Error line=16777215, 128 20 | Active breakpoints=526344, 11583231 21 | Folding lines=12365473, -16777201 22 | -------------------------------------------------------------------------------- /22 DS/Dev_cpp 配置/themes/Monokai.syntax: -------------------------------------------------------------------------------- 1 | [Editor.Custom] 2 | Assembler=clFuchsia, $021D160B, 0, 0, 0 3 | Character=$0067DBE6, $00222827, 0, 0, 0 4 | Comment=$006F8488, $00222827, 0, 0, 0 5 | Float=$00833AFF, $02222827, 0, 0, 0 6 | Hexadecimal=$00833AFF, $02222827, 0, 0, 0 7 | Identifier=$002EE2A6, $02222827, 0, 0, 0 8 | Illegal Char=$000000FB, $02222827, 0, 0, 0 9 | Number=$00FF81AE, $00222827, 0, 0, 0 10 | Octal=$00833AFF, $02222827, 0, 0, 0 11 | Preprocessor=$007226F9, $02222827, 0, 0, 0 12 | Reserved Word=$00EFD952, $02222827, 0, 1, 0 13 | Space=$1F222827, $02222827, 0, 0, 0 14 | String=$0067DBE6, $02222827, 0, 0, 0 15 | Symbol=$007226F9, $02222827, 0, 0, 0 16 | Selected text=16777215, 5921367 17 | Gutter=9080976, 2238503 18 | Breakpoints=16777215, 16742263 19 | Error line=16777215, 255 20 | Active breakpoints=16777215, 16711680 21 | Folding lines=192, 5328448 22 | -------------------------------------------------------------------------------- /22 DS/Dev_cpp 配置/themes/Pink.syntax: -------------------------------------------------------------------------------- 1 | [Editor.Custom] 2 | Assembler=$00FFAB79, $001E1E1E, 0, 0, 0 3 | Character=$00ACFFFF, $001E1E1E, 0, 0, 0 4 | Comment=clSilver, $001E1E1E, 0, 0, 0 5 | Float=clYellow, $001E1E1E, 0, 0, 0 6 | Hexadecimal=$0047B37F, $001E1E1E, 0, 0, 0 7 | Identifier=$00FFDDFF, $001E1E1E, 0, 0, 0 8 | Illegal Char=$000000FB, clNone, 0, 0, 0 9 | Number=clYellow, $001E1E1E, 0, 0, 0 10 | Octal=$0047B37F, $001E1E1E, 0, 0, 0 11 | Preprocessor=$00FFA2FF, $001E1E1E, 0, 0, 0 12 | Reserved Word=$009D3CFF, $001E1E1E, 0, 0, 0 13 | Space=$00D8D8D8, $001E1E1E, 0, 0, 0 14 | String=$00ACFFFF, $001E1E1E, 0, 0, 0 15 | Symbol=$00FF6FFF, $001E1E1E, 0, 0, 0 16 | Selected text=13684944, 0 17 | Gutter=16777215, 1973790 18 | Breakpoints=16777215, 32768 19 | Error line=16777215, 255 20 | Active breakpoints=16777215, 16711680 21 | Folding lines=16711680, 5328448 22 | -------------------------------------------------------------------------------- /22 DS/Dev_cpp 配置/themes/README.md: -------------------------------------------------------------------------------- 1 | 大部分主题配置来自:[themes-for-Dev-CPP ](https://github.com/optimize-2/themes-for-Dev-CPP) 2 | 3 | 在 Windows 下将其复制到 `%HOMEPATH%\AppData\Roaming\Dev-Cpp` 即可在 Dev_cpp 中设置这些主题,或者双击 `copy.bat` 脚本 -------------------------------------------------------------------------------- /22 DS/Dev_cpp 配置/themes/Sakura.syntax: -------------------------------------------------------------------------------- 1 | [Editor.Custom] 2 | Assembler=clFuchsia, $021D160B, 0, 0, 0 3 | Character=$0039E455, $001D160B, 0, 0, 0 4 | Comment=$00E09A1E, $001D160B, 0, 1, 0 5 | Float=$00833AFF, $021D160B, 0, 0, 0 6 | Hexadecimal=$00833AFF, $021D160B, 0, 0, 0 7 | Identifier=$00CE9FD7, $021D160B, 0, 0, 0 8 | Illegal Char=$000000FB, $021D160B, 0, 0, 0 9 | Number=$00ED4BE4, $021D160B, 0, 0, 0 10 | Octal=$00833AFF, $021D160B, 0, 0, 0 11 | Preprocessor=$008080FF, $021D160B, 0, 0, 0 12 | Reserved Word=$00DC9AC4, $021D160B, 0, 0, 0 13 | Space=$1F1D160B, $021D160B, 0, 0, 0 14 | String=$00EB32DD, $021D160B, 0, 0, 0 15 | Symbol=$00FF80FF, $021D160B, 0, 0, 0 16 | Selected text=16776960, 1906187 17 | Gutter=16777215, 3552302 18 | Breakpoints=16777215, 52377 19 | Error line=16777215, 1184469 20 | Active breakpoints=16777215, 16763904 21 | Folding lines=192, 5328448 22 | -------------------------------------------------------------------------------- /22 DS/Dev_cpp 配置/themes/Vector.syntax: -------------------------------------------------------------------------------- 1 | [Editor.Custom] 2 | Assembler=clRed, $021D160B, 0, 0, 0 3 | Character=$000080FF, $001D160B, 0, 0, 0 4 | Comment=$00FF8000, $001D160B, 0, 0, 0 5 | Float=$000080FF, $021D160B, 0, 0, 0 6 | Hexadecimal=$000080FF, $021D160B, 0, 0, 0 7 | Identifier=clWhite, $021D160B, 0, 0, 0 8 | Illegal Char=$000000FB, $021D160B, 0, 0, 0 9 | Number=$000080FF, $021D160B, 0, 0, 0 10 | Octal=$000080FF, $021D160B, 0, 0, 0 11 | Preprocessor=$004080FF, $021D160B, 0, 0, 0 12 | Reserved Word=$0080FF80, $021D160B, 0, 0, 0 13 | Space=clSilver, $021D160B, 0, 0, 0 14 | String=$000080FF, $021D160B, 0, 0, 0 15 | Symbol=clGray, $021D160B, 0, 0, 0 16 | Selected text=12632256, 1906187 17 | Gutter=12632256, 3552302 18 | Breakpoints=16777215, 32896 19 | Error line=16777215, 128 20 | Active breakpoints=16777215, 8421376 21 | Folding lines=12632256, 5328448 22 | -------------------------------------------------------------------------------- /22 DS/Dev_cpp 配置/themes/copy.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem copy syntax to Dev-Cpp 3 | if not exist %HOMEPATH%\AppData\Roaming\Dev-Cpp md %HOMEPATH%\AppData\Roaming\Dev-Cpp 4 | copy *.syntax %HOMEPATH%\AppData\Roaming\Dev-Cpp\*.syntax 5 | pause -------------------------------------------------------------------------------- /22 DS/Dev_cpp 配置/themes/one-dark-pro.syntax: -------------------------------------------------------------------------------- 1 | [Editor.Custom] 2 | Assembler=clBlack, $00342C28, 0, 0, 0 3 | Character=$00517A61, $00342C28, 0, 0, 0 4 | Comment=clGray, $00342C28, 0, 1, 0 5 | Float=$00447CD1, $00342C28, 0, 0, 0 6 | Hexadecimal=$00447CD1, $00342C28, 0, 0, 0 7 | Identifier=$00BFB2AB, $00342C28, 0, 0, 0 8 | Illegal Char=$0079B769, $00342C28, 0, 0, 0 9 | Number=$00447CD1, $00342C28, 0, 0, 0 10 | Octal=$00447CD1, $00342C28, 0, 0, 0 11 | Preprocessor=$0079B769, $00342C28, 0, 0, 0 12 | Reserved Word=$00DD78C6, $00342C28, 0, 0, 0 13 | Space=clWhite, $00342C28, 0, 0, 0 14 | String=$0079B769, $00342C28, 0, 0, 0 15 | Symbol=$00DD78C6, $00342C28, 0, 0, 0 16 | Selected text=12563115, 5851200 17 | Gutter=5592405, 2829099 18 | Breakpoints=12365473, 2302798 19 | Error line=16777215, 128 20 | Active breakpoints=12563115, 3419176 21 | Folding lines=12365473, -16777201 22 | -------------------------------------------------------------------------------- /22 DS/README.md: -------------------------------------------------------------------------------- 1 | ## 22 DS 2 | 3 | 22 级数据结构历次作业题的一些解析,还有一些乱七八糟的东西。 4 | 5 | - `Archive` 下为 pdf 版本,可能更新不及时。 6 | - `Ref` 中包含可能会需要查找的一些内容。 7 | - `Templates` 中包含一些可能会用到的板子。 8 | - `Simtool_debug` 中为大作业 debug 辅助工具。 9 | 10 | 有疑问可以提 `issue` 或邮件联系。 11 | 12 | github 的渲染支持较差,建议本地查看或 pdf 查看。 13 | -------------------------------------------------------------------------------- /22 DS/Ref/.DS+bug全扫除计划.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/Ref/.DS+bug全扫除计划.pdf -------------------------------------------------------------------------------- /22 DS/Ref/ASCII.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/Ref/ASCII.JPG -------------------------------------------------------------------------------- /22 DS/Ref/Priority.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/Ref/Priority.JPG -------------------------------------------------------------------------------- /22 DS/Ref/T1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/Ref/T1.pdf -------------------------------------------------------------------------------- /22 DS/Ref/T2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/Ref/T2.pdf -------------------------------------------------------------------------------- /22 DS/Ref/T3-链表.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/Ref/T3-链表.pdf -------------------------------------------------------------------------------- /22 DS/Ref/T4-栈与队.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/Ref/T4-栈与队.pdf -------------------------------------------------------------------------------- /22 DS/Ref/ctype.h.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/Ref/ctype.h.JPG -------------------------------------------------------------------------------- /22 DS/Ref/return_val.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/Ref/return_val.PNG -------------------------------------------------------------------------------- /22 DS/Ref/stdio.h.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/Ref/stdio.h.JPG -------------------------------------------------------------------------------- /22 DS/Ref/stdlib.h.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/Ref/stdlib.h.JPG -------------------------------------------------------------------------------- /22 DS/Ref/string.h.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/Ref/string.h.JPG -------------------------------------------------------------------------------- /22 DS/Simtool_debug/README.md: -------------------------------------------------------------------------------- 1 | # 22级DS综合作业 Debug 辅助工具 2 | 3 | $Author : \mathcal{Red}$ 4 | 5 | ## simtool_debug 6 | 7 | ### 使用说明 8 | 9 | - 默认输入文件与综合作业要求相同,放在 `CWD` (运行目录)下,即 `shell` 当前所在目录下(命令行前面显示的那个目录,可使用命令 `cd` 切换); 10 | 11 | - usage:`.\simtool_debug [ []] [--reverse]`(“[ ]”表示括号中为可选参数) 12 | 13 | example:`.\simtool_debug 1000 16 out.txt debug.txt 5 --reverse`,将 $N=1000,\,M=16$ 的结果 输出到 `out.txt`,并将 SAMPLE_HASH 与 WORD_INFO 信息输出到 `debug.txt`,其中 Hash 为倒序输出; 14 | 15 | - 在命令行中执行二进制文件,接受 $3$~$6$ 个参数,前 $2$ 个参数与综合作业要求相同,第 $3$ 个参数为默认输出文件路径,第 $4$ 个参数为 Debug 信息输出文件路径,第 $5$ 个参数为 Debug 信息内容,默认为 `SAMPLE_HASH | SOME_HASH`,可选列表见附录,掩码方式(即若 `mode & type`,则代表 `type` 生效),最后一个参数若为 `--reverse`,则代表将 Hash 倒序输出; 16 | 17 | - 仅支持 Windows; 18 | 19 | - 因为一些特殊原因跑的很慢。(但是进度条很好玩) 20 | 21 | ### 附录 22 | 23 | | MODE | VAL | FORMAT | PS | 24 | | ----------- | ---- | ---------- | -------------------------------- | 25 | | SAMPLE_HASH | 1 | %-10s: %Ms | | 26 | | SOME_HASH | 2 | %-10s: %Ms | HammingDistance <= 1 in example | 27 | | WORD_INFO | 4 | %-20s: %4d | Feature word and frequency | 28 | | MORE_HASH | 8 | %-10s: %Ms | HammingDistance <= 3 in example | 29 | 30 | ## comparator 31 | 32 | ### 使用说明 33 | 34 | - usage: `.\comparator ` 35 | - 输出两个文件的差异,若两个文件在忽略多余空格与末尾空行的条件下完全相同,则输出 `Same`。最多输出 10 行差异。 36 | 37 | ## 常数表 38 | 39 | ```c 40 | 41 | const int some[] = {1, 25, 38, 59, 83, 101, 111, 148, 160, 200, 201, 226, 301, 305, 327, 341, 391, 401, 467, 472, 486, 501, 536, 538, 577, 601, 614, 682, 700, 701, 705, 774, 801, 890, 901, 917, 944, 945, 950, 961, 972, 973, 976}; 42 | 43 | const int more[] = {1, 4, 7, 10, 13, 15, 16, 18, 24, 25, 28, 29, 30, 33, 37, 38, 39, 41, 42, 43, 44, 45, 46, 47, 48, 49, 51, 52, 54, 58, 59, 62, 64, 68, 71, 77, 78, 79, 81, 82, 83, 84, 85, 87, 89, 90, 91, 93, 94, 96, 97, 100, 101, 102, 103, 105, 107, 111, 114, 115, 116, 118, 124, 126, 128, 129, 132, 136, 139, 142, 146, 147, 148, 149, 151, 152, 155, 156, 158, 159, 160, 161, 162, 165, 167, 169, 170, 173, 174, 175, 176, 177, 182, 184, 186, 187, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 203, 206, 207, 211, 212, 213, 215, 216, 217, 218, 220, 221, 222, 225, 226, 227, 228, 229, 230, 231, 232, 233, 235, 238, 240, 241, 242, 246, 252, 253, 254, 257, 261, 263, 264, 266, 267, 271, 275, 277, 281, 282, 283, 286, 288, 292, 296, 298, 300, 301, 302, 303, 304, 305, 308, 310, 311, 313, 314, 315, 316, 318, 319, 320, 322, 326, 327, 328, 331, 333, 334, 335, 336, 337, 341, 344, 345, 352, 353, 356, 358, 359, 364, 366, 367, 368, 370, 371, 372, 377, 380, 381, 382, 388, 389, 390, 391, 392, 395, 396, 400, 401, 402, 404, 407, 409, 416, 417, 420, 421, 422, 423, 424, 425, 429, 436, 437, 438, 439, 440, 442, 443, 446, 448, 449, 451, 453, 458, 460, 461, 465, 467, 468, 469, 471, 472, 473, 474, 475, 480, 482, 486, 488, 489, 490, 491, 494, 496, 497, 498, 499, 501, 502, 504, 506, 508, 509, 510, 511, 512, 513, 515, 517, 520, 522, 523, 526, 529, 531, 532, 534, 536, 537, 538, 539, 540, 542, 543, 545, 546, 547, 548, 549, 550, 552, 553, 554, 557, 559, 562, 563, 565, 570, 571, 572, 574, 576, 577, 578, 582, 583, 585, 587, 589, 590, 591, 592, 594, 595, 596, 597, 601, 607, 610, 611, 612, 614, 616, 618, 621, 630, 632, 641, 643, 650, 651, 652, 654, 655, 657, 665, 666, 667, 668, 669, 670, 672, 674, 675, 676, 677, 678, 679, 681, 682, 683, 684, 685, 686, 687, 688, 689, 694, 695, 696, 700, 701, 702, 703, 704, 705, 706, 712, 713, 715, 720, 727, 728, 729, 730, 731, 735, 743, 752, 754, 757, 758, 759, 763, 764, 765, 766, 767, 768, 769, 771, 774, 776, 778, 779, 781, 782, 786, 790, 792, 795, 796, 797, 799, 801, 804, 806, 809, 813, 814, 817, 821, 823, 824, 828, 829, 830, 835, 838, 842, 844, 845, 846, 849, 850, 851, 855, 856, 857, 859, 861, 863, 865, 868, 871, 872, 873, 874, 876, 878, 880, 881, 882, 883, 884, 885, 886, 888, 889, 890, 892, 893, 894, 896, 899, 901, 902, 905, 906, 907, 914, 917, 918, 919, 922, 923, 924, 925, 926, 929, 931, 934, 935, 940, 942, 944, 945, 950, 951, 955, 956, 958, 959, 961, 962, 963, 964, 965, 967, 971, 972, 973, 974, 975, 976, 977, 978, 979, 982, 983, 984, 989, 990, 991, 992}; 44 | ``` 45 | -------------------------------------------------------------------------------- /22 DS/Simtool_debug/README.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/Simtool_debug/README.pdf -------------------------------------------------------------------------------- /22 DS/Simtool_debug/comparator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using std::cin, std::cout, std::endl; 5 | using std::ifstream; 6 | using std::string; 7 | void SetColor(WORD forecolor = 4, WORD backgroudcolor = 0) 8 | { 9 | HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); 10 | SetConsoleTextAttribute(hCon, forecolor | backgroudcolor); 11 | } 12 | void cut_space(string &s) 13 | { 14 | for (auto i = s.begin(); i != s.end(); i++) 15 | if (*i == ' ' && (i == s.begin() || *(i - 1) == ' ' || i + 1 == s.end())) 16 | s.erase(i--); 17 | } 18 | int max_diffs = 10; 19 | int main(int argc, char **argv) 20 | { 21 | if (argc > 4 || argc < 3) 22 | return cout << "Error: Wrong number of arguments." << endl, 1; 23 | ifstream fin1(argv[1]); 24 | ifstream fin2(argv[2]); 25 | if (argc == 4) 26 | max_diffs = atoi(argv[3]); 27 | if (!fin1.is_open()) 28 | return cout << "Error: Cannot open file " << argv[1] << endl, 1; 29 | if (!fin2.is_open()) 30 | return cout << "Error: Cannot open file " << argv[2] << endl, 1; 31 | int line = 0, flag = 0; 32 | while (!fin1.eof() && !fin2.eof()) 33 | { 34 | string expected, found; 35 | getline(fin1, expected); 36 | getline(fin2, found); 37 | line++; 38 | cut_space(expected); 39 | cut_space(found); 40 | if (expected != found) 41 | { 42 | if (flag++ == max_diffs) 43 | { 44 | cout << "Too many differences." << endl; 45 | SetColor(7, 0); 46 | return 0; 47 | } 48 | SetColor(4, 0); 49 | cout << "Difference at line " << line << endl; 50 | SetColor(7, 0); 51 | cout << "Expected: " << expected << endl; 52 | cout << "Found: " << found << endl; 53 | cout << " "; 54 | SetColor(4, 0); 55 | auto i = expected.begin(), j = found.begin(); 56 | for (; i != expected.end() && j != found.end(); i++, j++) 57 | cout << (*i == *j ? ' ' : '^'); 58 | for (; i != expected.end(); i++) 59 | cout << '^'; 60 | for (; j != found.end(); j++) 61 | cout << '^'; 62 | cout << endl; 63 | } 64 | } 65 | auto &fin = fin1.eof() ? fin2 : fin1; 66 | string s; 67 | while (getline(fin, s)) 68 | if (!s.empty()) 69 | { 70 | SetColor(4, 0); 71 | cout << "Different number of lines." << endl; 72 | SetColor(7, 0); 73 | cout << "The surplus line is: " << s << endl; 74 | return 0; 75 | } 76 | SetColor(2, 0); 77 | if (!flag) 78 | cout << "Same" << endl; 79 | SetColor(7, 0); 80 | return 0; 81 | } -------------------------------------------------------------------------------- /22 DS/Simtool_debug/simtool_debug.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/Simtool_debug/simtool_debug.exe -------------------------------------------------------------------------------- /22 DS/Templates/README.md: -------------------------------------------------------------------------------- 1 | # 一些板子 2 | 3 | - list.c:双向链表,可伪装为循环链表,可用以实现栈、队列等数据结构。 4 | 5 | 实现了绝大部分常用的链表操作,包括:插入、删除、查找、遍历、反转、合并、拆分、清空、销毁等。 6 | 7 | 自定义数据类型,需要实现复制、比较、打印函数。 8 | 9 | 可通过在头部添加 `#define STACK` 或 `#define QUEUE` 开启模拟栈/队列模式。 10 | 11 | - stack.c:本质为数组栈。 12 | 13 | 可自定义数据类型。 14 | 15 | - queue.c:本质为数组实现的循环队列。 16 | 17 | 可自定义数据类型。 18 | 19 | - qsort.c:快速快速排序,快速定义比较函数。 20 | -------------------------------------------------------------------------------- /22 DS/Templates/list.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define STACK 6 | #define QUEUE 7 | 8 | // typedef int ele; 9 | typedef char *ele; 10 | 11 | // return 1 if a > b, -1 if a < b, 0 if a == b 12 | int equal_ele(ele a, ele b); 13 | // copy the value of src to dest 14 | void copy_ele(ele *dest, ele src); 15 | // print the value of val 16 | void print_ele(ele val); 17 | 18 | // int equal_ele(ele a, ele b) { 19 | // return a == b; 20 | // } 21 | // void copy_ele(ele *dest, ele src) { 22 | // *dest = src; 23 | // } 24 | // void print_ele(ele val) { 25 | // printf("%d ", val); 26 | // } 27 | 28 | int equal_ele(ele a, ele b) { 29 | return strcmp(a, b); 30 | } 31 | void copy_ele(ele *dest, ele src) { 32 | *dest = (char *)malloc(sizeof(char) * (strlen(src) + 1)); 33 | strcpy(*dest, src); 34 | } 35 | void print_ele(ele val) { 36 | printf("%s ", val); 37 | } 38 | 39 | typedef struct node { 40 | ele val; 41 | struct node *next, *prev; 42 | } Node, *pNode; 43 | 44 | pNode new_node(ele); 45 | 46 | typedef struct { 47 | pNode head, tail; 48 | int size; 49 | } List, *pList; 50 | 51 | // Iterate over the elements in the list named "list". 52 | // During the loop, assign the list elements to the variable "node" 53 | // Note: you can't remove the current node in the loop 54 | #define list_for_each(list, node) for (pNode node = list->head; node != NULL; node = node->next) 55 | 56 | // Iterate over the elements in the list named "list" in reverse order. 57 | #define list_for_each_reverse(list, node) \ 58 | for (pNode node = list->tail; node != NULL; node = node->prev) 59 | 60 | // Iterate over the elements in the list named "list" from the node "node". 61 | #define list_for_each_from(list, node) for (; node != NULL; node = cycle_next(list, node)) 62 | 63 | // Iterate over the elements in the list named "list" from the node "node" in reverse order. 64 | #define list_for_each_from_reverse(list, node) for (; node != NULL; node = cycle_prev(list, node)) 65 | 66 | // Iterate over the elements in the list named "list". 67 | // Note: you can remove the node in the loop, 68 | // but you can't remove the next node of the current node 69 | #define list_for_each_safe(list, node, next) \ 70 | for (pNode node = list->head, next = node == NULL ? NULL : node->next; node != NULL; \ 71 | node = next, next = node == NULL ? NULL : node->next) 72 | 73 | pList new_list(); 74 | pList new_list_from_array(ele *, int); 75 | 76 | pNode get_head(pList); 77 | pNode get_tail(pList); 78 | pNode find(pList, ele); 79 | pNode find_k(pList, ele, int); 80 | pNode find_at(pList, int); 81 | pNode find_eq(pList, ele, int (*)(ele, ele)); 82 | 83 | void insert_tail(pList, ele); 84 | void insert_head(pList, ele); 85 | void insert_before(pList, pNode, ele); 86 | void insert_after(pList, pNode, ele); 87 | void insert_at(pList, int, ele); 88 | 89 | void remove_head(pList); 90 | void remove_tail(pList); 91 | void remove_node(pList, pNode); 92 | void remove_at(pList, int); 93 | void remove_val(pList, ele); 94 | void remove_k(pList, ele, int); 95 | 96 | pNode cycle_next(pList, pNode); 97 | pNode cycle_prev(pList, pNode); 98 | 99 | void print_list(pList); 100 | int is_empty(pList); 101 | int size(pList); 102 | pList copy(pList); 103 | void reverse(pList); 104 | void clear(pList); 105 | void concat(pList, pList); 106 | pList split(pList, int); 107 | void free_list(pList); 108 | 109 | #ifdef QUEUE 110 | typedef List Queue, *pQueue; 111 | pQueue new_queue(); 112 | void enqueue(pQueue, ele); 113 | ele dequeue(pQueue); 114 | ele front(pQueue); 115 | #endif 116 | 117 | #ifdef STACK 118 | typedef List Stack, *pStack; 119 | pStack new_stack(); 120 | void push(pStack, ele); 121 | ele pop(pStack); 122 | ele top(pStack); 123 | #endif 124 | 125 | char *num[10] = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}; 126 | 127 | int main() { 128 | 129 | #ifdef STACK 130 | /* Stack Test */ 131 | printf("Stack Test\n"); 132 | pStack stack = new_stack(); 133 | for (int i = 0; i < 10; i++) { 134 | push(stack, num[i]); 135 | } 136 | print_list(stack); 137 | for (int i = 0; i < 10; i++) { 138 | printf("%s ", pop(stack)); 139 | } 140 | printf("\n\n"); 141 | free_list(stack); 142 | #endif 143 | 144 | #ifdef QUEUE 145 | /* Queue Test */ 146 | printf("Queue Test\n"); 147 | pQueue queue = new_queue(); 148 | for (int i = 0; i < 10; i++) { 149 | enqueue(queue, num[i]); 150 | } 151 | print_list(queue); 152 | for (int i = 0; i < 10; i++) { 153 | printf("%s ", dequeue(queue)); 154 | } 155 | printf("\n\n"); 156 | #endif 157 | /* List Test */ 158 | printf("List Test\n"); 159 | pList list = new_list_from_array(num, 10); 160 | /* 161 | num here is an one-dimensional array. 162 | if you use char num_two[10][10] = {"zero", "one", ...} here, 163 | the func cannot infer the size of the elements in the array. 164 | Because the size of the elements is expected to be sizeof(ele) = sizeof(char*). 165 | */ 166 | print_list(list); 167 | 168 | remove_at(list, 3); 169 | print_list(list); 170 | 171 | insert_head(list, "HEAD"); 172 | insert_after(list, find(list, "five"), "{AFTER five}"); 173 | insert_before(list, find_at(list, 2), "{BEFORE loc 2}"); 174 | insert_tail(list, "TAIL"); 175 | insert_tail(list, "five"); 176 | insert_tail(list, "five"); 177 | insert_tail(list, "five"); 178 | print_list(list); 179 | 180 | remove_val(list, "five"); 181 | print_list(list); 182 | 183 | pList list2 = split(list, 5); 184 | print_list(list); 185 | print_list(list2); 186 | 187 | concat(list, list2); 188 | print_list(list); 189 | 190 | reverse(list); 191 | print_list(list); 192 | 193 | clear(list); 194 | 195 | return 0; 196 | } 197 | 198 | /* --------------------------------------------------------------- */ 199 | /* --------------------------------------------------------------- */ 200 | /* --------------------------------------------------------------- */ 201 | /* --------------------------------------------------------------- */ 202 | /* --------------------------------------------------------------- */ 203 | /* --------------------------------------------------------------- */ 204 | /* --------------------------------------------------------------- */ 205 | /* --------------------------------------------------------------- */ 206 | /* --------------------------------------------------------------- */ 207 | /* --------------------------------------------------------------- */ 208 | /* --------------------------------------------------------------- */ 209 | /* --------------------------------------------------------------- */ 210 | 211 | // create a node, return the pointer to the node 212 | // not used by user 213 | pNode new_node(ele val) { 214 | pNode node = (pNode)malloc(sizeof(Node)); 215 | copy_ele(&node->val, val); 216 | node->next = node->prev = NULL; 217 | return node; 218 | } 219 | 220 | // create a list, return the pointer to the list 221 | pList new_list() { 222 | pList list = (pList)malloc(sizeof(List)); 223 | list->head = list->tail = NULL; 224 | list->size = 0; 225 | return list; 226 | } 227 | 228 | // create a list from an array, return the pointer to the list 229 | // the length of the array is "len" 230 | // Note: the array should be a one-dimensional array 231 | pList new_list_from_array(ele *arr, int len) { 232 | pList list = new_list(); 233 | for (int i = 0; i < len; i++) { 234 | insert_tail(list, arr[i]); 235 | } 236 | return list; 237 | } 238 | 239 | // get the head of the list 240 | pNode get_head(pList list) { 241 | return list->head; 242 | } 243 | 244 | // get the tail of the list 245 | pNode get_tail(pList list) { 246 | return list->tail; 247 | } 248 | 249 | // find the k-th node with the value "val" 250 | pNode find_k(pList list, ele val, int k) { 251 | int cnt = 0; 252 | list_for_each(list, node) { 253 | if (equal_ele(node->val, val) == 0) { 254 | cnt++; 255 | if (cnt == k) { 256 | return node; 257 | } 258 | } 259 | } 260 | return NULL; 261 | } 262 | 263 | // find the first node with the value "val" using the function "equal_user" 264 | // the function "equal_user" should return 0 if the two values are equal 265 | pNode find_eq(pList list, ele val, int (*equal_user)(ele, ele)) { 266 | list_for_each(list, node) { 267 | if (equal_user(node->val, val) == 0) { 268 | return node; 269 | } 270 | } 271 | return NULL; 272 | } 273 | 274 | // find the first node with the value "val" 275 | pNode find(pList list, ele val) { 276 | return find_eq(list, val, equal_ele); 277 | } 278 | 279 | // find the node at the index "index" 280 | pNode find_at(pList list, int index) { 281 | if (index < 0 || index >= list->size) { 282 | printf("Error: index out of range\n"); 283 | return NULL; 284 | } 285 | pNode node; 286 | if (index < list->size / 2) { 287 | node = list->head; 288 | for (int i = 0; i < index; i++) { 289 | node = node->next; 290 | } 291 | } else { 292 | node = list->tail; 293 | for (int i = list->size - 1; i > index; i--) { 294 | node = node->prev; 295 | } 296 | } 297 | return node; 298 | } 299 | 300 | // count the number of nodes with the value "val"6 301 | int count(pList list, ele val) { 302 | int cnt = 0; 303 | list_for_each(list, node) { 304 | if (equal_ele(node->val, val) == 0) { 305 | cnt++; 306 | } 307 | } 308 | return cnt; 309 | } 310 | 311 | // insert a node with the value "val" to the tail of the list 312 | void insert_tail(pList list, ele val) { 313 | pNode node = new_node(val); 314 | if (list->size == 0) { 315 | list->head = list->tail = node; 316 | } else { 317 | list->tail->next = node; 318 | node->prev = list->tail; 319 | list->tail = node; 320 | } 321 | list->size++; 322 | } 323 | 324 | // insert a node with the value "val" to the head of the list 325 | void insert_head(pList list, ele val) { 326 | pNode node = new_node(val); 327 | if (list->size == 0) { 328 | list->head = list->tail = node; 329 | } else { 330 | list->head->prev = node; 331 | node->next = list->head; 332 | list->head = node; 333 | } 334 | list->size++; 335 | } 336 | 337 | // insert a node with the value "val" before the node "node" 338 | void insert_before(pList list, pNode node, ele val) { 339 | if (node == list->head) { 340 | insert_head(list, val); 341 | } else { 342 | pNode newNode = new_node(val); 343 | newNode->next = node; 344 | newNode->prev = node->prev; 345 | node->prev->next = newNode; 346 | node->prev = newNode; 347 | list->size++; 348 | } 349 | } 350 | 351 | // insert a node with the value "val" after the node "node" 352 | void insert_after(pList list, pNode node, ele val) { 353 | if (node == list->tail) { 354 | insert_tail(list, val); 355 | } else { 356 | pNode newNode = new_node(val); 357 | newNode->next = node->next; 358 | newNode->prev = node; 359 | node->next->prev = newNode; 360 | node->next = newNode; 361 | list->size++; 362 | } 363 | } 364 | 365 | // insert a node with the value "val" at the position "pos" 366 | void insert_at(pList list, int pos, ele val) { 367 | if (pos < 0 || pos > list->size) { 368 | printf("Error: insert position out of range\n"); 369 | return; 370 | } 371 | if (pos == list->size) { 372 | insert_tail(list, val); 373 | } else { 374 | pNode node = find_at(list, pos); 375 | insert_before(list, node, val); 376 | } 377 | } 378 | 379 | // remove the head node and free the memory 380 | void remove_head(pList list) { 381 | if (list->size == 0) { 382 | printf("Error: list is empty\n"); 383 | return; 384 | } 385 | pNode node = list->head; 386 | list->head = list->head->next; 387 | if (list->head == NULL) { 388 | list->tail = NULL; 389 | } else { 390 | list->head->prev = NULL; 391 | } 392 | free(node); 393 | list->size--; 394 | } 395 | 396 | // remove the tail node and free the memory 397 | void remove_tail(pList list) { 398 | if (list->size == 0) { 399 | printf("Error: list is empty\n"); 400 | return; 401 | } 402 | pNode node = list->tail; 403 | list->tail = list->tail->prev; 404 | if (list->tail == NULL) { 405 | list->head = NULL; 406 | } else { 407 | list->tail->next = NULL; 408 | } 409 | free(node); 410 | list->size--; 411 | } 412 | 413 | // remove the node "node" and free the memory 414 | void remove_node(pList list, pNode node) { 415 | if (list->size == 0) { 416 | printf("Error: list is empty\n"); 417 | return; 418 | } 419 | if (node == list->head) { 420 | remove_head(list); 421 | } else if (node == list->tail) { 422 | remove_tail(list); 423 | } else { 424 | node->prev->next = node->next; 425 | node->next->prev = node->prev; 426 | free(node); 427 | list->size--; 428 | } 429 | } 430 | 431 | // remove the node at the position "pos" 432 | void remove_at(pList list, int pos) { 433 | if (pos < 0 || pos >= list->size) { 434 | printf("Error: remove position out of range\n"); 435 | return; 436 | } 437 | pNode node = find_at(list, pos); 438 | remove_node(list, node); 439 | } 440 | 441 | // remove all nodes with the value "val" 442 | void remove_val(pList list, ele val) { 443 | list_for_each_safe(list, node, next) { 444 | if (equal_ele(node->val, val) == 0) { 445 | remove_node(list, node); 446 | } 447 | } 448 | } 449 | 450 | // remove k-th node with the value "val" 451 | void remove_k(pList list, ele val, int k) { 452 | int cnt = 0; 453 | list_for_each_safe(list, node, next) { 454 | if (equal_ele(node->val, val) == 0) { 455 | cnt++; 456 | if (cnt == k) { 457 | remove_node(list, node); 458 | return; 459 | } 460 | } 461 | } 462 | } 463 | 464 | // next node if the list is a cycle list 465 | // if the node is NULL, return the head node 466 | pNode cycle_next(pList list, pNode node) { 467 | if (node == NULL) { 468 | return list->head; 469 | } 470 | return node->next == NULL ? list->head : node->next; 471 | } 472 | 473 | // previous node if the list is a cycle list 474 | // if the node is NULL, return the tail node 475 | pNode cycle_prev(pList list, pNode node) { 476 | if (node == NULL) { 477 | return list->tail; 478 | } 479 | return node->prev == NULL ? list->tail : node->prev; 480 | } 481 | 482 | // print the list 483 | void print_list(pList list) { 484 | list_for_each(list, node) { 485 | print_ele(node->val); 486 | } 487 | printf("\n"); 488 | } 489 | 490 | // return 1 if the list is empty, otherwise return 0 491 | int is_empty(pList list) { 492 | return list->size == 0; 493 | } 494 | 495 | // return the size of the list 496 | int size(pList list) { 497 | return list->size; 498 | } 499 | 500 | // copy the list 501 | pList copy(pList list) { 502 | pList newList = new_list(); 503 | list_for_each(list, node) { 504 | insert_tail(newList, node->val); 505 | } 506 | return newList; 507 | } 508 | 509 | // reverse the list 510 | void reverse(pList list) { 511 | pNode node = list->head; 512 | list->head = list->tail; 513 | list->tail = node; 514 | while (node != NULL) { 515 | pNode next = node->next; 516 | node->next = node->prev; 517 | node->prev = next; 518 | node = next; 519 | } 520 | } 521 | 522 | // clear the list 523 | // free all nodes and set the list to empty 524 | void clear(pList list) { 525 | pNode node = list->head; 526 | while (node != NULL) { 527 | pNode next = node->next; 528 | free(node); 529 | node = next; 530 | } 531 | list->head = list->tail = NULL; 532 | list->size = 0; 533 | } 534 | 535 | // concat list2 to the tail of list1 536 | // list2 will be empty after concat 537 | void concat(pList list1, pList list2) { 538 | if (list1->size == 0) { 539 | list1->head = list2->head; 540 | list1->tail = list2->tail; 541 | } else if (list2->size != 0) { 542 | list1->tail->next = list2->head; 543 | list2->head->prev = list1->tail; 544 | list1->tail = list2->tail; 545 | } 546 | list1->size += list2->size; 547 | list2->head = list2->tail = NULL; 548 | list2->size = 0; 549 | } 550 | 551 | // split the list at the position "pos" 552 | // return the list after the position "pos" 553 | // the list before the position "pos" will be the original list 554 | pList split(pList list, int pos) { 555 | if (pos < 0 || pos >= list->size) { 556 | printf("Error: split position out of range\n"); 557 | return NULL; 558 | } 559 | pList newList = new_list(); 560 | if (pos == 0) { 561 | newList->head = list->head; 562 | newList->tail = list->tail; 563 | newList->size = list->size; 564 | list->head = list->tail = NULL; 565 | list->size = 0; 566 | } else if (pos == list->size - 1) { 567 | newList->head = list->tail; 568 | newList->tail = list->tail; 569 | newList->size = 1; 570 | list->tail = list->tail->prev; 571 | list->tail->next = NULL; 572 | list->size--; 573 | } else { 574 | pNode node = find_at(list, pos); 575 | newList->head = node->next; 576 | newList->tail = list->tail; 577 | newList->size = list->size - pos; 578 | list->tail = node; 579 | list->tail->next = NULL; 580 | list->size = pos; 581 | } 582 | return newList; 583 | } 584 | 585 | // free the list 586 | // free all nodes and the list itself 587 | void free_list(pList list) { 588 | clear(list); 589 | free(list); 590 | } 591 | 592 | #ifdef QUEUE 593 | pQueue new_queue() { 594 | return new_list(); 595 | } 596 | ele front(pQueue queue) { 597 | if (queue->size == 0) { 598 | printf("Error: queue is empty\n"); 599 | return 0; 600 | } 601 | return queue->head->val; 602 | } 603 | void enqueue(pQueue queue, ele val) { 604 | insert_tail(queue, val); 605 | } 606 | ele dequeue(pQueue queue) { 607 | ele val = front(queue); 608 | remove_head(queue); 609 | return val; 610 | } 611 | #endif 612 | 613 | #ifdef STACK 614 | pStack new_stack() { 615 | return new_list(); 616 | } 617 | ele top(pStack stack) { 618 | if (stack->size == 0) { 619 | printf("Error: stack is empty\n"); 620 | return 0; 621 | } 622 | return stack->tail->val; 623 | } 624 | void push(pStack stack, ele val) { 625 | insert_tail(stack, val); 626 | } 627 | ele pop(pStack stack) { 628 | ele val = top(stack); 629 | remove_tail(stack); 630 | return val; 631 | } 632 | #endif -------------------------------------------------------------------------------- /22 DS/Templates/qsort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int a[] = {34, 213, 75, 123, 678, 223, 56, 22, 67, 34, 987, 234, 52, 72, 87, 6 | 34, 67, 784, 154, 968, 134, 7687, 16, 56, 125, 635, 7, 44, 594, 488}; 7 | double b[] = {10.67, 5.292, 2.986, 1.553, 4.900, 2.755, 7.741, 10.99, 9.786, 2.378, 8 | 10.33, 9.072, 6.087, 7.006, 3.235, 5.241, 6.605, 6.748, 3.629, 10.03}; 9 | 10 | #define cmp_func(size) \ 11 | int cmp_##size(const void *_a, const void *_b) /*参数格式固定*/ \ 12 | { \ 13 | size a = *(size *)_a; /*强制类型转换*/ \ 14 | size b = *(size *)_b; \ 15 | if (a != b) \ 16 | return a > b ? 1 : -1; \ 17 | return 0; \ 18 | } 19 | 20 | // 宏定义式比较函数 21 | // 用法:参数为简单类型名,如 int,double,生成对应的比较函数,复杂的类型需要自己写 22 | cmp_func(int); 23 | // 等价于 24 | // int cmp_int(const void *_a, const void *_b) { 25 | // int a = *(int *)_a; 26 | // int b = *(int *)_b; 27 | // if (a != b) 28 | // return a > b ? 1 : -1; 29 | // return 0; 30 | // } 31 | 32 | cmp_func(double); 33 | int main() { 34 | qsort(a, sizeof a / sizeof(int), sizeof a[0], cmp_int); 35 | for (int i = 0; i < sizeof a / sizeof(int); i++) { 36 | printf("%d ", a[i]); 37 | } 38 | printf("\n"); 39 | qsort(b, sizeof b / sizeof(double), sizeof b[0], cmp_double); 40 | for (int i = 0; i < sizeof b / sizeof(double); i++) { 41 | printf("%.2lf ", b[i]); 42 | } 43 | return 0; 44 | } -------------------------------------------------------------------------------- /22 DS/Templates/queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | const int MAX_SIZE = 2000; 5 | // 队列的元素类型,可以自行修改 6 | typedef int ele; 7 | /* typedef struct { 8 | int x; 9 | int y; 10 | } ele; */ 11 | 12 | typedef struct { 13 | int front, rare; 14 | ele *ele; 15 | } Queue, *pQueue; 16 | // 创建一个队列,返回队列指针 17 | pQueue new_queue() { 18 | pQueue q = (pQueue)malloc(sizeof(Queue)); 19 | q->ele = (ele *)malloc(MAX_SIZE * sizeof(ele)); 20 | q->front = q->rare = 0; 21 | return q; 22 | } 23 | // 判断队列是否为空 24 | int is_empty(pQueue q) { 25 | return q->front == q->rare; 26 | } 27 | // 判断队列是否已满 28 | int is_full(pQueue q) { 29 | return (q->rare + 1) % MAX_SIZE == q->front; 30 | } 31 | // 入队 32 | void enqueue(pQueue q, ele e) { 33 | if (is_full(q)) { 34 | printf("Queue is full!"); 35 | return; 36 | } 37 | q->ele[q->rare] = e; 38 | q->rare = (q->rare + 1) % MAX_SIZE; 39 | } 40 | // 出队 41 | ele dequeue(pQueue q) { 42 | if (is_empty(q)) { 43 | printf("Queue is empty!"); 44 | exit(1); // or return a special ele value 45 | } 46 | ele e = q->ele[q->front]; 47 | q->front = (q->front + 1) % MAX_SIZE; 48 | return e; 49 | } 50 | // 释放队列空间,考试时不用写 51 | void free_queue(pQueue q) { 52 | free(q->ele); 53 | free(q); 54 | } 55 | 56 | int main() { 57 | pQueue q = new_queue(); 58 | for (int i = 0; i < 10; i++) { 59 | enqueue(q, i); 60 | } 61 | for (int i = 0; i < 10; i++) { 62 | printf("%d ", dequeue(q)); 63 | } 64 | free_queue(q); 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /22 DS/Templates/stack.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | const int MAX_SIZE = 2000; 5 | 6 | // 栈的元素类型,可以自行修改 7 | typedef int ele; 8 | /* typedef struct { 9 | int x; 10 | int y; 11 | } ele; */ 12 | 13 | typedef struct { 14 | int top; 15 | ele *bottom; 16 | } stack, *pStack; 17 | // 创建一个栈,返回栈的指针 18 | pStack new_stack() { 19 | pStack s = (pStack)malloc(sizeof(stack)); 20 | s->bottom = (ele *)malloc(sizeof(ele) * MAX_SIZE); 21 | s->top = 0; 22 | return s; 23 | } 24 | // 判断栈是否为空 25 | int is_empty(pStack s) { 26 | return s->top == 0; 27 | } 28 | // 判断栈是否已满 29 | int is_full(pStack s) { 30 | return s->top == MAX_SIZE; 31 | } 32 | // 压入元素 33 | void push(pStack s, ele x) { 34 | if (is_full(s)) { 35 | printf("Stack is full!"); 36 | return; 37 | } 38 | s->bottom[s->top++] = x; 39 | } 40 | // 弹出栈顶元素 41 | ele pop(pStack s) { 42 | if (is_empty(s)) { 43 | printf("Stack is empty!"); 44 | exit(1); // or return a special ele value 45 | } 46 | return s->bottom[--s->top]; 47 | } 48 | // 返回栈顶元素,不弹出 49 | ele top(pStack s) { 50 | return s->bottom[s->top - 1]; 51 | } 52 | // 释放栈空间,考试时不用写 53 | void free_stack(pStack s) { 54 | free(s->bottom); 55 | free(s); 56 | } 57 | 58 | int main() { 59 | pStack s = new_stack(); 60 | for (int i = 0; i < 10; i++) { 61 | push(s, i); 62 | } 63 | for (int i = 0; i < 10; i++) { 64 | printf("%d ", pop(s)); 65 | } 66 | free_stack(s); 67 | return 0; 68 | } -------------------------------------------------------------------------------- /22 DS/assets/image-20230404173011756.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/assets/image-20230404173011756.png -------------------------------------------------------------------------------- /22 DS/assets/image-20230404175707391.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AoiroRed/Library/b4826383f5fe52f3fb349537ea84181803b5a9eb/22 DS/assets/image-20230404175707391.png -------------------------------------------------------------------------------- /22 DS/期中复刻?/T2/check.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | from gen import gen 4 | from colorama import Fore 5 | from alive_progress import alive_bar 6 | 7 | 8 | CHECK_TIMES = 20 9 | EXE_PATH = '.\\bin\\std.exe' 10 | STD_PATH = '.\\bin\\std.exe' 11 | 12 | def check(exe = EXE_PATH): 13 | with open('test.in', 'w') as f: 14 | sys.stdout = f 15 | gen() 16 | f.close() 17 | os.system(f'.\\{exe} < .\\test.in > .\\test.out') 18 | os.system(STD_PATH + ' < .\\test.in > .\\test.ans') 19 | with open('test.out', 'r') as out, open('test.ans', 'r') as ans: 20 | if out.read() != ans.read(): 21 | return False 22 | return True 23 | 24 | 25 | if __name__ == '__main__': 26 | # exe = input('Executable file name: ') 27 | with alive_bar(CHECK_TIMES) as bar: 28 | for _ in range(CHECK_TIMES): 29 | if not check(): 30 | sys.stdout = sys.__stdout__ 31 | print(Fore.RED + 'Wrong Answer' + Fore.RESET) 32 | exit(0) 33 | bar() 34 | os.remove('test.in') 35 | os.remove('test.out') 36 | os.remove('test.ans') 37 | sys.stdout = sys.__stdout__ 38 | print(Fore.GREEN + 'Accepted' + Fore.RESET) 39 | -------------------------------------------------------------------------------- /22 DS/期中复刻?/T2/gen.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | import os 4 | 5 | INT_MAX = 2147483647 6 | INT_MIN = -2147483648 7 | 8 | 9 | def gen(MAXN=100000): 10 | n = random.randint(MAXN//3, MAXN) 11 | nums = [random.randint(INT_MIN, INT_MAX) for _ in range(min(MAXN//3, 1000))] 12 | print(n) 13 | print(*random.choices(nums, k=n)) 14 | 15 | 16 | if __name__ == '__main__': 17 | if len(sys.argv) == 1: 18 | gen(20) 19 | else: 20 | os.makedirs('data', exist_ok=True) 21 | for i in range(1, int(sys.argv[1]) + 1): 22 | dataIn = os.path.join('data', '%d.in' % i) 23 | dataOut = os.path.join('data', '%d.out' % i) 24 | with open(dataIn, 'w') as f: 25 | sys.stdout = f 26 | gen() 27 | f.close() 28 | os.system('.\\bin\\std.exe < ./%s > ./%s' % (dataIn, dataOut)) 29 | -------------------------------------------------------------------------------- /22 DS/期中复刻?/T2/std.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // #define STACK 6 | // #define QUEUE 7 | 8 | // typedef int ele; 9 | // typedef char *ele; 10 | typedef struct { 11 | int num; 12 | int cnt; 13 | } ele; 14 | 15 | // return 1 if a > b, -1 if a < b, 0 if a == b 16 | int equal_ele(ele a, ele b); 17 | // copy the value of src to dest 18 | void copy_ele(ele *dest, ele src); 19 | // print the value of val 20 | void print_ele(ele val); 21 | 22 | int equal_ele(ele a, ele b) { 23 | return a.num - b.num; 24 | } 25 | void copy_ele(ele *dest, ele src) { 26 | dest->num = src.num; 27 | dest->cnt = src.cnt; 28 | } 29 | void print_ele(ele val) { 30 | printf("%d %d", val.num, val.cnt); 31 | } 32 | 33 | // int equal_ele(ele a, ele b) { 34 | // return strcmp(a, b); 35 | // } 36 | // void copy_ele(ele *dest, ele src) { 37 | // *dest = (char *)malloc(sizeof(char) * (strlen(src) + 1)); 38 | // strcpy(*dest, src); 39 | // } 40 | // void print_ele(ele val) { 41 | // printf("%s ", val); 42 | // } 43 | 44 | typedef struct node { 45 | ele val; 46 | struct node *next, *prev; 47 | } Node, *pNode; 48 | 49 | pNode new_node(ele); 50 | 51 | typedef struct { 52 | pNode head, tail; 53 | int size; 54 | } List, *pList; 55 | 56 | // Iterate over the elements in the list named "list". 57 | // During the loop, assign the list elements to the variable "node" 58 | // Note: you can't remove the current node in the loop 59 | #define list_for_each(list, node) for (pNode node = list->head; node != NULL; node = node->next) 60 | 61 | // Iterate over the elements in the list named "list" in reverse order. 62 | #define list_for_each_reverse(list, node) \ 63 | for (pNode node = list->tail; node != NULL; node = node->prev) 64 | 65 | // Iterate over the elements in the list named "list" from the node "node". 66 | #define list_for_each_from(list, node) for (; node != NULL; node = cycle_next(list, node)) 67 | 68 | // Iterate over the elements in the list named "list" from the node "node" in reverse order. 69 | #define list_for_each_from_reverse(list, node) for (; node != NULL; node = cycle_prev(list, node)) 70 | 71 | // Iterate over the elements in the list named "list". 72 | // Note: you can remove the node in the loop, 73 | // but you can't remove the next node of the current node 74 | #define list_for_each_safe(list, node, next) \ 75 | for (pNode node = list->head, next = node == NULL ? NULL : node->next; node != NULL; \ 76 | node = next, next = node == NULL ? NULL : node->next) 77 | 78 | pList new_list(); 79 | pList new_list_from_array(ele *, int); 80 | 81 | pNode get_head(pList); 82 | pNode get_tail(pList); 83 | pNode find(pList, ele); 84 | pNode find_k(pList, ele, int); 85 | pNode find_at(pList, int); 86 | pNode find_eq(pList, ele, int (*)(ele, ele)); 87 | 88 | void insert_tail(pList, ele); 89 | void insert_head(pList, ele); 90 | void insert_before(pList, pNode, ele); 91 | void insert_after(pList, pNode, ele); 92 | void insert_at(pList, int, ele); 93 | 94 | void remove_head(pList); 95 | void remove_tail(pList); 96 | void remove_node(pList, pNode); 97 | void remove_at(pList, int); 98 | void remove_val(pList, ele); 99 | void remove_k(pList, ele, int); 100 | 101 | pNode cycle_next(pList, pNode); 102 | pNode cycle_prev(pList, pNode); 103 | 104 | void print_list(pList); 105 | int is_empty(pList); 106 | int size(pList); 107 | pList copy(pList); 108 | void reverse(pList); 109 | void clear(pList); 110 | void concat(pList, pList); 111 | pList split(pList, int); 112 | void free_list(pList); 113 | 114 | #ifdef QUEUE 115 | typedef List Queue, *pQueue; 116 | pQueue new_queue(); 117 | void enqueue(pQueue, ele); 118 | ele dequeue(pQueue); 119 | ele front(pQueue); 120 | #endif 121 | 122 | #ifdef STACK 123 | typedef List Stack, *pStack; 124 | pStack new_stack(); 125 | void push(pStack, ele); 126 | ele pop(pStack); 127 | ele top(pStack); 128 | #endif 129 | 130 | int cnt; 131 | int main() { 132 | int n; 133 | pList list = new_list(); 134 | scanf("%d", &n); 135 | while (n--) { 136 | ele x; 137 | scanf("%d", &x.num); 138 | x.cnt = 1; 139 | pNode node = find(list, x); 140 | // add cnt to this function 141 | if (node == NULL) { 142 | insert_tail(list, x); 143 | } else { 144 | node->val.cnt++; 145 | insert_head(list, node->val); 146 | remove_node(list, node); 147 | } 148 | } 149 | n = 0; 150 | list_for_each(list, node) { 151 | print_ele(node->val); 152 | printf("\n"); 153 | if (++n == 5) { 154 | break; 155 | } 156 | } 157 | printf("%d\n", cnt); 158 | return 0; 159 | } 160 | 161 | /* --------------------------------------------------------------- */ 162 | /* --------------------------------------------------------------- */ 163 | /* --------------------------------------------------------------- */ 164 | /* --------------------------------------------------------------- */ 165 | /* --------------------------------------------------------------- */ 166 | /* --------------------------------------------------------------- */ 167 | /* --------------------------------------------------------------- */ 168 | /* --------------------------------------------------------------- */ 169 | /* --------------------------------------------------------------- */ 170 | /* --------------------------------------------------------------- */ 171 | /* --------------------------------------------------------------- */ 172 | /* --------------------------------------------------------------- */ 173 | 174 | // create a node, return the pointer to the node 175 | // not used by user 176 | pNode new_node(ele val) { 177 | pNode node = (pNode)malloc(sizeof(Node)); 178 | copy_ele(&node->val, val); 179 | node->next = node->prev = NULL; 180 | return node; 181 | } 182 | 183 | // create a list, return the pointer to the list 184 | pList new_list() { 185 | pList list = (pList)malloc(sizeof(List)); 186 | list->head = list->tail = NULL; 187 | list->size = 0; 188 | return list; 189 | } 190 | 191 | // create a list from an array, return the pointer to the list 192 | // the length of the array is "len" 193 | // Note: the array should be a one-dimensional array 194 | pList new_list_from_array(ele *arr, int len) { 195 | pList list = new_list(); 196 | for (int i = 0; i < len; i++) { 197 | insert_tail(list, arr[i]); 198 | } 199 | return list; 200 | } 201 | 202 | // get the head of the list 203 | pNode get_head(pList list) { 204 | return list->head; 205 | } 206 | 207 | // get the tail of the list 208 | pNode get_tail(pList list) { 209 | return list->tail; 210 | } 211 | 212 | // find the k-th node with the value "val" 213 | pNode find_k(pList list, ele val, int k) { 214 | int cnt = 0; 215 | list_for_each(list, node) { 216 | if (equal_ele(node->val, val) == 0) { 217 | cnt++; 218 | if (cnt == k) { 219 | return node; 220 | } 221 | } 222 | } 223 | return NULL; 224 | } 225 | 226 | // find the first node with the value "val" using the function "equal_user" 227 | // the function "equal_user" should return 0 if the two values are equal 228 | pNode find_eq(pList list, ele val, int (*equal_user)(ele, ele)) { 229 | list_for_each(list, node) { 230 | cnt++; 231 | if (equal_user(node->val, val) == 0) { 232 | return node; 233 | } 234 | } 235 | return NULL; 236 | } 237 | 238 | // find the first node with the value "val" 239 | pNode find(pList list, ele val) { 240 | return find_eq(list, val, equal_ele); 241 | } 242 | 243 | // find the node at the index "index" 244 | pNode find_at(pList list, int index) { 245 | if (index < 0 || index >= list->size) { 246 | printf("Error: index out of range\n"); 247 | return NULL; 248 | } 249 | pNode node = NULL; 250 | if (index < list->size / 2) { 251 | node = list->head; 252 | for (int i = 0; i < index; i++) { 253 | node = node->next; 254 | } 255 | } else { 256 | node = list->tail; 257 | for (int i = list->size - 1; i > index; i--) { 258 | node = node->prev; 259 | } 260 | } 261 | return node; 262 | } 263 | 264 | // count the number of nodes with the value "val" 265 | int count(pList list, ele val) { 266 | int cnt = 0; 267 | list_for_each(list, node) { 268 | if (equal_ele(node->val, val) == 0) { 269 | cnt++; 270 | } 271 | } 272 | return cnt; 273 | } 274 | 275 | // insert a node with the value "val" to the tail of the list 276 | void insert_tail(pList list, ele val) { 277 | pNode node = new_node(val); 278 | if (list->size == 0) { 279 | list->head = list->tail = node; 280 | } else { 281 | list->tail->next = node; 282 | node->prev = list->tail; 283 | list->tail = node; 284 | } 285 | list->size++; 286 | } 287 | 288 | // insert a node with the value "val" to the head of the list 289 | void insert_head(pList list, ele val) { 290 | pNode node = new_node(val); 291 | if (list->size == 0) { 292 | list->head = list->tail = node; 293 | } else { 294 | list->head->prev = node; 295 | node->next = list->head; 296 | list->head = node; 297 | } 298 | list->size++; 299 | } 300 | 301 | // insert a node with the value "val" before the node "node" 302 | void insert_before(pList list, pNode node, ele val) { 303 | if (node == list->head) { 304 | insert_head(list, val); 305 | } else { 306 | pNode newNode = new_node(val); 307 | newNode->next = node; 308 | newNode->prev = node->prev; 309 | node->prev->next = newNode; 310 | node->prev = newNode; 311 | list->size++; 312 | } 313 | } 314 | 315 | // insert a node with the value "val" after the node "node" 316 | void insert_after(pList list, pNode node, ele val) { 317 | if (node == list->tail) { 318 | insert_tail(list, val); 319 | } else { 320 | pNode newNode = new_node(val); 321 | newNode->next = node->next; 322 | newNode->prev = node; 323 | node->next->prev = newNode; 324 | node->next = newNode; 325 | list->size++; 326 | } 327 | } 328 | 329 | // insert a node with the value "val" at the position "pos" 330 | void insert_at(pList list, int pos, ele val) { 331 | if (pos < 0 || pos > list->size) { 332 | printf("Error: insert position out of range\n"); 333 | return; 334 | } 335 | if (pos == list->size) { 336 | insert_tail(list, val); 337 | } else { 338 | pNode node = find_at(list, pos); 339 | insert_before(list, node, val); 340 | } 341 | } 342 | 343 | // remove the head node and free the memory 344 | void remove_head(pList list) { 345 | if (list->size == 0) { 346 | printf("Error: list is empty\n"); 347 | return; 348 | } 349 | pNode node = list->head; 350 | list->head = list->head->next; 351 | if (list->head == NULL) { 352 | list->tail = NULL; 353 | } else { 354 | list->head->prev = NULL; 355 | } 356 | free(node); 357 | list->size--; 358 | } 359 | 360 | // remove the tail node and free the memory 361 | void remove_tail(pList list) { 362 | if (list->size == 0) { 363 | printf("Error: list is empty\n"); 364 | return; 365 | } 366 | pNode node = list->tail; 367 | list->tail = list->tail->prev; 368 | if (list->tail == NULL) { 369 | list->head = NULL; 370 | } else { 371 | list->tail->next = NULL; 372 | } 373 | free(node); 374 | list->size--; 375 | } 376 | 377 | // remove the node "node" and free the memory 378 | void remove_node(pList list, pNode node) { 379 | if (list->size == 0) { 380 | printf("Error: list is empty\n"); 381 | return; 382 | } 383 | if (node == list->head) { 384 | remove_head(list); 385 | } else if (node == list->tail) { 386 | remove_tail(list); 387 | } else { 388 | node->prev->next = node->next; 389 | node->next->prev = node->prev; 390 | free(node); 391 | list->size--; 392 | } 393 | } 394 | 395 | // remove the node at the position "pos" 396 | void remove_at(pList list, int pos) { 397 | if (pos < 0 || pos >= list->size) { 398 | printf("Error: remove position out of range\n"); 399 | return; 400 | } 401 | pNode node = find_at(list, pos); 402 | remove_node(list, node); 403 | } 404 | 405 | // remove all nodes with the value "val" 406 | void remove_val(pList list, ele val) { 407 | list_for_each_safe(list, node, next) { 408 | if (equal_ele(node->val, val) == 0) { 409 | remove_node(list, node); 410 | } 411 | } 412 | } 413 | 414 | // remove k-th node with the value "val" 415 | void remove_k(pList list, ele val, int k) { 416 | int cnt = 0; 417 | list_for_each_safe(list, node, next) { 418 | if (equal_ele(node->val, val) == 0) { 419 | cnt++; 420 | if (cnt == k) { 421 | remove_node(list, node); 422 | return; 423 | } 424 | } 425 | } 426 | } 427 | 428 | // next node if the list is a cycle list 429 | // if the node is NULL, return the head node 430 | pNode cycle_next(pList list, pNode node) { 431 | if (node == NULL) { 432 | return list->head; 433 | } 434 | return node->next == NULL ? list->head : node->next; 435 | } 436 | 437 | // previous node if the list is a cycle list 438 | // if the node is NULL, return the tail node 439 | pNode cycle_prev(pList list, pNode node) { 440 | if (node == NULL) { 441 | return list->tail; 442 | } 443 | return node->prev == NULL ? list->tail : node->prev; 444 | } 445 | 446 | // print the list 447 | void print_list(pList list) { 448 | list_for_each(list, node) { 449 | print_ele(node->val); 450 | } 451 | printf("\n"); 452 | } 453 | 454 | // return 1 if the list is empty, otherwise return 0 455 | int is_empty(pList list) { 456 | return list->size == 0; 457 | } 458 | 459 | // return the size of the list 460 | int size(pList list) { 461 | return list->size; 462 | } 463 | 464 | // copy the list 465 | pList copy(pList list) { 466 | pList newList = new_list(); 467 | list_for_each(list, node) { 468 | insert_tail(newList, node->val); 469 | } 470 | return newList; 471 | } 472 | 473 | // reverse the list 474 | void reverse(pList list) { 475 | pNode node = list->head; 476 | list->head = list->tail; 477 | list->tail = node; 478 | while (node != NULL) { 479 | pNode next = node->next; 480 | node->next = node->prev; 481 | node->prev = next; 482 | node = next; 483 | } 484 | } 485 | 486 | // clear the list 487 | // free all nodes and set the list to empty 488 | void clear(pList list) { 489 | pNode node = list->head; 490 | while (node != NULL) { 491 | pNode next = node->next; 492 | free(node); 493 | node = next; 494 | } 495 | list->head = list->tail = NULL; 496 | list->size = 0; 497 | } 498 | 499 | // concat list2 to the tail of list1 500 | // list2 will be empty after concat 501 | void concat(pList list1, pList list2) { 502 | if (list1->size == 0) { 503 | list1->head = list2->head; 504 | list1->tail = list2->tail; 505 | } else if (list2->size != 0) { 506 | list1->tail->next = list2->head; 507 | list2->head->prev = list1->tail; 508 | list1->tail = list2->tail; 509 | } 510 | list1->size += list2->size; 511 | list2->head = list2->tail = NULL; 512 | list2->size = 0; 513 | } 514 | 515 | // split the list at the position "pos" 516 | // return the list after the position "pos" 517 | // the list before the position "pos" will be the original list 518 | pList split(pList list, int pos) { 519 | if (pos < 0 || pos >= list->size) { 520 | printf("Error: split position out of range\n"); 521 | return NULL; 522 | } 523 | pList newList = new_list(); 524 | if (pos == 0) { 525 | newList->head = list->head; 526 | newList->tail = list->tail; 527 | newList->size = list->size; 528 | list->head = list->tail = NULL; 529 | list->size = 0; 530 | } else if (pos == list->size - 1) { 531 | newList->head = list->tail; 532 | newList->tail = list->tail; 533 | newList->size = 1; 534 | list->tail = list->tail->prev; 535 | list->tail->next = NULL; 536 | list->size--; 537 | } else { 538 | pNode node = find_at(list, pos); 539 | newList->head = node->next; 540 | newList->tail = list->tail; 541 | newList->size = list->size - pos; 542 | list->tail = node; 543 | list->tail->next = NULL; 544 | list->size = pos; 545 | } 546 | return newList; 547 | } 548 | 549 | // free the list 550 | // free all nodes and the list itself 551 | void free_list(pList list) { 552 | clear(list); 553 | free(list); 554 | } 555 | 556 | #ifdef QUEUE 557 | pQueue new_queue() { 558 | return new_list(); 559 | } 560 | ele front(pQueue queue) { 561 | if (queue->size == 0) { 562 | printf("Error: queue is empty\n"); 563 | return 0; 564 | } 565 | return queue->head->val; 566 | } 567 | void enqueue(pQueue queue, ele val) { 568 | insert_tail(queue, val); 569 | } 570 | ele dequeue(pQueue queue) { 571 | ele val = front(queue); 572 | remove_head(queue); 573 | return val; 574 | } 575 | #endif 576 | 577 | #ifdef STACK 578 | pStack new_stack() { 579 | return new_list(); 580 | } 581 | ele top(pStack stack) { 582 | if (stack->size == 0) { 583 | printf("Error: stack is empty\n"); 584 | return 0; 585 | } 586 | return stack->tail->val; 587 | } 588 | void push(pStack stack, ele val) { 589 | insert_tail(stack, val); 590 | } 591 | ele pop(pStack stack) { 592 | ele val = top(stack); 593 | remove_tail(stack); 594 | return val; 595 | } 596 | #endif -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # Library 2 | 3 | Red‘s library for some notes. 4 | 5 | only `22 DS` now. 6 | --------------------------------------------------------------------------------