mirror of
https://gitee.com/Lamdonn/varch.git
synced 2025-12-06 16:56:42 +08:00
add graph, add windows vscode debug config
This commit is contained in:
parent
c91eabcb57
commit
a390743342
2
.gitignore
vendored
2
.gitignore
vendored
@ -25,5 +25,5 @@ node_modules
|
|||||||
dist
|
dist
|
||||||
dist-ssr
|
dist-ssr
|
||||||
*.local
|
*.local
|
||||||
.vscode/
|
# .vscode/
|
||||||
built/
|
built/
|
||||||
23
.vscode/c_cpp_properties.json
vendored
Normal file
23
.vscode/c_cpp_properties.json
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Win32",
|
||||||
|
"includePath": [
|
||||||
|
"D:\\MinGW\\include", // Include system path, stdio.h ...
|
||||||
|
"D:\\MinGW\\lib\\gcc\\mingw32\\6.3.0\\include", // Include system path, stddef.h ...
|
||||||
|
"${workspaceFolder}/**"
|
||||||
|
],
|
||||||
|
"defines": [
|
||||||
|
"_DEBUG",
|
||||||
|
"UNICODE",
|
||||||
|
"_UNICODE"
|
||||||
|
],
|
||||||
|
"windowsSdkVersion": "8.1",
|
||||||
|
"compilerPath": "D:\\MinGW\\bin\\gdb.exe", // MinGW gdb path
|
||||||
|
"cStandard": "c17",
|
||||||
|
"cppStandard": "c++17",
|
||||||
|
"intelliSenseMode": "gcc-x64" // gcc-x64, gcc-arm64, msvc-x64, clang-x64, clang-arm64
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
||||||
29
.vscode/launch.json
vendored
Normal file
29
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "gcc.exe build and debug active file",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}\\built\\app.exe", // executable file
|
||||||
|
"args": [],
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"environment": [],
|
||||||
|
"externalConsole": true, // printf
|
||||||
|
"MIMode": "gdb", // gcc-x64, gcc-arm64, msvc-x64, clang-x64, clang-arm64
|
||||||
|
"miDebuggerPath": "D:\\MinGW\\bin\\gdb.exe", // MinGW gdb path
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"description": "Enable pretty-printing for gdb",
|
||||||
|
"text": "-enable-pretty-printing",
|
||||||
|
"ignoreFailures": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"preLaunchTask": "C/C++: gcc.exe build active file"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"init.h": "c"
|
||||||
|
}
|
||||||
|
}
|
||||||
30
.vscode/tasks.json
vendored
Normal file
30
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "cppbuild",
|
||||||
|
"label": "C/C++: gcc.exe build active file",
|
||||||
|
// "command": "D:\\MinGW\\bin\\gcc.exe",
|
||||||
|
"command": "make", // use makefile
|
||||||
|
"args": [
|
||||||
|
// "-fdiagnostics-color=always",
|
||||||
|
// "-g",
|
||||||
|
// "${file}",
|
||||||
|
// "-o",
|
||||||
|
// "${fileDirname}\\${fileBasenameNoExtension}.exe"
|
||||||
|
"CFLAG=-g"
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
],
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"detail": "Task generated by Debugger."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": "2.0.0"
|
||||||
|
}
|
||||||
@ -13,7 +13,7 @@ It has the characteristics of **simplicity, universality, and efficiency**, with
|
|||||||
|
|
||||||
| module | version | usage | path | describe |
|
| module | version | usage | path | describe |
|
||||||
|:-------------|:---------|:-----------------------------|:--------------------------------------|:--------------------------------------|
|
|:-------------|:---------|:-----------------------------|:--------------------------------------|:--------------------------------------|
|
||||||
| overall | 00.01.01 | [link](README.md) | ./ | Overall
|
| overall | 00.02.00 | [link](README.md) | ./ | Overall
|
||||||
| init | 01.00.00 | [link](/doc/init.md) | ./source/00_application | Initialize export module
|
| init | 01.00.00 | [link](/doc/init.md) | ./source/00_application | Initialize export module
|
||||||
| console | 01.00.00 | [link](/doc/console.md) | ./source/00_application/console | Console command input, combined with the 'command' module, parsing commands entered in the console
|
| console | 01.00.00 | [link](/doc/console.md) | ./source/00_application/console | Console command input, combined with the 'command' module, parsing commands entered in the console
|
||||||
| arg | 01.00.00 | [link](/doc/arg.md) | ./source/01_general | Indefinite parameters, obtain the number of indefinite parameters and specified parameters
|
| arg | 01.00.00 | [link](/doc/arg.md) | ./source/01_general | Indefinite parameters, obtain the number of indefinite parameters and specified parameters
|
||||||
@ -47,6 +47,7 @@ It has the characteristics of **simplicity, universality, and efficiency**, with
|
|||||||
| str | 01.00.00 | [link](/doc/str.md) | ./source/03_container | String class
|
| str | 01.00.00 | [link](/doc/str.md) | ./source/03_container | String class
|
||||||
| tree | 01.00.00 | [link](/doc/tree.md) | ./source/03_container | Universal tree container
|
| tree | 01.00.00 | [link](/doc/tree.md) | ./source/03_container | Universal tree container
|
||||||
| vector | 01.00.00 | [link](/doc/vector.md) | ./source/03_container | Universal vector(array) container
|
| vector | 01.00.00 | [link](/doc/vector.md) | ./source/03_container | Universal vector(array) container
|
||||||
|
| graph | 01.00.00 | [link](/doc/graph.md) | ./source/03_container | Universal graph container
|
||||||
| check | 01.00.00 | [link](/doc/check.md) | ./source/04_algorithm | Verification algorithm, sum check, parity check, XOR check, LRC check
|
| check | 01.00.00 | [link](/doc/check.md) | ./source/04_algorithm | Verification algorithm, sum check, parity check, XOR check, LRC check
|
||||||
| crc | 01.00.00 | [link](/doc/check.md) | ./source/04_algorithm | Universal and standard CRC algorithms
|
| crc | 01.00.00 | [link](/doc/check.md) | ./source/04_algorithm | Universal and standard CRC algorithms
|
||||||
| encrypt | 01.00.00 | [link](/doc/encrypt.md) | ./source/04_algorithm | Encryption and decryption algorithms
|
| encrypt | 01.00.00 | [link](/doc/encrypt.md) | ./source/04_algorithm | Encryption and decryption algorithms
|
||||||
|
|||||||
@ -13,7 +13,7 @@ varch(we-architecture,意为我们的框架库)是嵌入式C语言常用
|
|||||||
|
|
||||||
| module | version | usage | path | describe |
|
| module | version | usage | path | describe |
|
||||||
|:-------------|:---------|:-----------------------------|:--------------------------------------|:--------------------------------------|
|
|:-------------|:---------|:-----------------------------|:--------------------------------------|:--------------------------------------|
|
||||||
| overall | 00.01.01 | [link](README.md) | ./ | 整体
|
| overall | 00.02.00 | [link](README.md) | ./ | 整体
|
||||||
| init | 01.00.00 | [link](/doc/init.md) | ./source/00_application | 初始化导出模块
|
| init | 01.00.00 | [link](/doc/init.md) | ./source/00_application | 初始化导出模块
|
||||||
| console | 01.00.00 | [link](/doc/console.md) | ./source/00_application/console | 控制台命令输入,结合 `command` 模块,解析在控制台中输入的命令
|
| console | 01.00.00 | [link](/doc/console.md) | ./source/00_application/console | 控制台命令输入,结合 `command` 模块,解析在控制台中输入的命令
|
||||||
| arg | 01.00.00 | [link](/doc/arg.md) | ./source/01_general | 不定参数,获取不定参数和指定参数的个数
|
| arg | 01.00.00 | [link](/doc/arg.md) | ./source/01_general | 不定参数,获取不定参数和指定参数的个数
|
||||||
@ -40,13 +40,14 @@ varch(we-architecture,意为我们的框架库)是嵌入式C语言常用
|
|||||||
| dict | 01.00.00 | [link](/doc/dict.md) | ./source/03_container | 通用字典容器,基于哈希表实现
|
| dict | 01.00.00 | [link](/doc/dict.md) | ./source/03_container | 通用字典容器,基于哈希表实现
|
||||||
| heap | 01.00.00 | [link](/doc/heap.md) | ./source/03_container | 通用堆容器
|
| heap | 01.00.00 | [link](/doc/heap.md) | ./source/03_container | 通用堆容器
|
||||||
| list | 01.00.00 | [link](/doc/list.md) | ./source/03_container | 通用列表容器,单链接和支持内部迭代器
|
| list | 01.00.00 | [link](/doc/list.md) | ./source/03_container | 通用列表容器,单链接和支持内部迭代器
|
||||||
| map | 01.00.00 | [link](/doc/map.md) | ./source/03_container | 通用地图容器,基于RB-tree实现
|
| map | 01.00.00 | [link](/doc/map.md) | ./source/03_container | 通用映射容器,基于RB-tree实现
|
||||||
| queue | 01.00.00 | [link](/doc/queue.md) | ./source/03_container | 通用队列容器
|
| queue | 01.00.00 | [link](/doc/queue.md) | ./source/03_container | 通用队列容器
|
||||||
| set | 01.00.00 | [link](/doc/set.md) | ./source/03_container | 通用集合容器,基于RB-tree实现
|
| set | 01.00.00 | [link](/doc/set.md) | ./source/03_container | 通用集合容器,基于RB-tree实现
|
||||||
| stack | 01.00.00 | [link](/doc/stack.md) | ./source/03_container | 通用栈式容器
|
| stack | 01.00.00 | [link](/doc/stack.md) | ./source/03_container | 通用栈式容器
|
||||||
| str | 01.00.00 | [link](/doc/str.md) | ./source/03_container | 字符串类
|
| str | 01.00.00 | [link](/doc/str.md) | ./source/03_container | 字符串类
|
||||||
| tree | 01.00.00 | [link](/doc/tree.md) | ./source/03_container | 通用树容器
|
| tree | 01.00.00 | [link](/doc/tree.md) | ./source/03_container | 通用树容器
|
||||||
| vector | 01.00.00 | [link](/doc/vector.md) | ./source/03_container | 通用向量(数组)容器
|
| vector | 01.00.00 | [link](/doc/vector.md) | ./source/03_container | 通用向量(数组)容器
|
||||||
|
| graph | 01.00.00 | [link](/doc/graph.md) | ./source/03_container | 通用图容器
|
||||||
| check | 01.00.00 | [link](/doc/check.md) | ./source/04_algorithm | 校验算法,求和校验,奇偶校验,异或校验,LRC校验
|
| check | 01.00.00 | [link](/doc/check.md) | ./source/04_algorithm | 校验算法,求和校验,奇偶校验,异或校验,LRC校验
|
||||||
| crc | 01.00.00 | [link](/doc/check.md) | ./source/04_algorithm | 通用标准CRC算法
|
| crc | 01.00.00 | [link](/doc/check.md) | ./source/04_algorithm | 通用标准CRC算法
|
||||||
| encrypt | 01.00.00 | [link](/doc/encrypt.md) | ./source/04_algorithm | 加密解密算法
|
| encrypt | 01.00.00 | [link](/doc/encrypt.md) | ./source/04_algorithm | 加密解密算法
|
||||||
|
|||||||
31
built.sh
Normal file
31
built.sh
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
exe_file="built/bin/app"
|
||||||
|
|
||||||
|
echo "cleaning..."
|
||||||
|
if [ -f $exe_file ]; then
|
||||||
|
rm $exe_file
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "compilling..."
|
||||||
|
|
||||||
|
if [ "$1" == "debug" ]; then
|
||||||
|
make CFLAG=-g
|
||||||
|
else
|
||||||
|
make
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f $exe_file ]; then
|
||||||
|
echo "#################################"
|
||||||
|
echo "# Compile success !!!..."
|
||||||
|
echo "#################################"
|
||||||
|
else
|
||||||
|
echo "#################################"
|
||||||
|
echo "*** Compile fail ***"
|
||||||
|
echo "#################################"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# find . -name *.h -o -name *.c | xargs wc -l
|
||||||
|
|
||||||
|
# enter key to continue
|
||||||
|
read -p "Press enter to continue"
|
||||||
764
doc/graph.md
Normal file
764
doc/graph.md
Normal file
@ -0,0 +1,764 @@
|
|||||||
|
## 介绍
|
||||||
|
|
||||||
|
图(Graph)是一种由节点(或称顶点)和边组成的数据结构,通常用于表示对象之间的关系。以下是图的基本概念及其特点:
|
||||||
|
|
||||||
|
### 1. 基本组成
|
||||||
|
- **节点(Vertex)**:图中的基本单位,表示对象。
|
||||||
|
- **边(Edge)**:连接两个节点的线,表示节点之间的关系。
|
||||||
|
|
||||||
|
### 2. 类型
|
||||||
|
- **有向图(Directed Graph)**:边有方向,表示从一个节点到另一个节点的单向关系。
|
||||||
|
- **无向图(Undirected Graph)**:边没有方向,表示节点之间的双向关系。
|
||||||
|
- **加权图(Weighted Graph)**:边带有权重,表示连接两个节点的代价或距离。
|
||||||
|
|
||||||
|
### 3. 表示方法
|
||||||
|
- **邻接矩阵(Adjacency Matrix)**:用一个二维数组表示节点之间的连接关系,数组中的值表示边的存在(1)或不存在(0),如果是加权图,则用边的权重表示。
|
||||||
|
|
||||||
|
- **邻接表(Adjacency List)**:用一个数组或链表表示每个节点的邻接节点,适用于稀疏图。
|
||||||
|
|
||||||
|
### 4. 应用
|
||||||
|
- **社交网络**:节点表示用户,边表示用户之间的关系。
|
||||||
|
- **网络路由**:节点表示路由器,边表示连接。
|
||||||
|
- **路径查找**:如地图应用中查找最短路径。
|
||||||
|
|
||||||
|
该模块实现了一个图的数据结构,包括基本的图操作,如添加和删除顶点与边,以及深度优先搜索(DFS)和广度优先搜索(BFS)等算法。该图支持有向图和无向图,适合于各种图论应用。
|
||||||
|
|
||||||
|
## 接口
|
||||||
|
|
||||||
|
### 创建和删除graph对象
|
||||||
|
|
||||||
|
```c
|
||||||
|
graph_t graph_create(int max, int directed);
|
||||||
|
```
|
||||||
|
|
||||||
|
创建并初始化一个图。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `max`: 图中最大顶点数。
|
||||||
|
- `directed`: 标志位,指示图是否为有向图(非零)或无向图(零)。
|
||||||
|
|
||||||
|
**返回**: 返回指向新创建图的指针,如果创建失败则返回NULL。
|
||||||
|
|
||||||
|
```c
|
||||||
|
void graph_delete(graph_t graph);
|
||||||
|
```
|
||||||
|
|
||||||
|
销毁图并释放相关资源。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向要销毁的图的指针。
|
||||||
|
|
||||||
|
**返回**: 无
|
||||||
|
|
||||||
|
例子
|
||||||
|
```c
|
||||||
|
graph_t graph = graph_create(10, 1);
|
||||||
|
graph_delete(graph);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 添加顶点
|
||||||
|
|
||||||
|
```c
|
||||||
|
int graph_add_vertex(graph_t graph, void *data, int size);
|
||||||
|
```
|
||||||
|
|
||||||
|
向图中添加一个顶点。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向要添加顶点的图的指针。
|
||||||
|
- `data`: 与顶点相关联的数据的指针。
|
||||||
|
- `size`: 要复制的数据的大小。
|
||||||
|
|
||||||
|
**返回**: 返回添加的顶点的索引,如果添加失败则返回-1。
|
||||||
|
|
||||||
|
例子
|
||||||
|
```c
|
||||||
|
void graph_traverse_int(int index, void *data, int size)
|
||||||
|
{
|
||||||
|
printf("graph[%d] %d\r\n", index, *(int *)data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_add_vertex(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(10, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 12), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 13), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 15), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 23), sizeof(int));
|
||||||
|
|
||||||
|
graph_ls(graph, graph_traverse_int);
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
其中 `la()` 为获取字面量地址的宏定义,具体可以参考 [test_graph.c](../test/test_graph.c) 文件
|
||||||
|
`graph_ls()` 线性搜索方法,下文介绍。
|
||||||
|
|
||||||
|
结果
|
||||||
|
```
|
||||||
|
graph[0] 12
|
||||||
|
graph[1] 13
|
||||||
|
graph[2] 15
|
||||||
|
graph[3] 23
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 添加边
|
||||||
|
|
||||||
|
```c
|
||||||
|
int graph_add_edge(graph_t graph, int start, int end, int weight);
|
||||||
|
```
|
||||||
|
|
||||||
|
向图中添加一条边。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向要添加边的图的指针。
|
||||||
|
- `start`: 起始顶点的索引。
|
||||||
|
- `end`: 结束顶点的索引。
|
||||||
|
- `weight`: 边的权重。
|
||||||
|
|
||||||
|
**返回**: 如果边成功添加返回1,失败返回0。
|
||||||
|
|
||||||
|
例子
|
||||||
|
```c
|
||||||
|
static void test_add_edge(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(10, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 12), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 13), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 15), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 23), sizeof(int));
|
||||||
|
|
||||||
|
printf("---------------\r\n");
|
||||||
|
|
||||||
|
graph_dfs(graph, 0, graph_traverse_int);
|
||||||
|
|
||||||
|
printf("---------------\r\n");
|
||||||
|
|
||||||
|
graph_add_edge(graph, 0, 1, 0);
|
||||||
|
graph_add_edge(graph, 0, 2, 0);
|
||||||
|
graph_add_edge(graph, 0, 3, 0);
|
||||||
|
graph_add_edge(graph, 1, 0, 0);
|
||||||
|
graph_add_edge(graph, 1, 2, 0);
|
||||||
|
graph_add_edge(graph, 1, 3, 0);
|
||||||
|
graph_add_edge(graph, 2, 3, 0);
|
||||||
|
|
||||||
|
graph_dfs(graph, 0, graph_traverse_int);
|
||||||
|
|
||||||
|
printf("---------------\r\n");
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`graph_dfs()` 为深度优先搜索方法,下文介绍
|
||||||
|
|
||||||
|
对比添加边前后搜索的情况,没有边连接的图搜不到下一个顶点
|
||||||
|
|
||||||
|
结果
|
||||||
|
```
|
||||||
|
---------------
|
||||||
|
graph[0] 12
|
||||||
|
---------------
|
||||||
|
graph[0] 12
|
||||||
|
graph[3] 23
|
||||||
|
graph[2] 15
|
||||||
|
graph[1] 13
|
||||||
|
---------------
|
||||||
|
```
|
||||||
|
|
||||||
|
### 移除顶点和边
|
||||||
|
|
||||||
|
```c
|
||||||
|
int graph_remove_vertex(graph_t graph, int index);
|
||||||
|
```
|
||||||
|
|
||||||
|
从图中移除指定的顶点及其关联的边。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向要移除顶点的图的指针。
|
||||||
|
- `index`: 要移除的顶点的索引。
|
||||||
|
|
||||||
|
**返回**: 如果顶点成功移除返回1,失败返回0。
|
||||||
|
|
||||||
|
```c
|
||||||
|
int graph_remove_edge(graph_t graph, int start, int end);
|
||||||
|
```
|
||||||
|
|
||||||
|
从图中移除指定的边。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向要移除边的图的指针。
|
||||||
|
- `start`: 边的起始顶点索引。
|
||||||
|
- `end`: 边的结束顶点索引。
|
||||||
|
|
||||||
|
**返回**: 如果边成功移除返回1,失败返回0。
|
||||||
|
|
||||||
|
例子
|
||||||
|
```c
|
||||||
|
static void test_remove(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(100, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 100), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 200), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 300), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 500), sizeof(int));
|
||||||
|
|
||||||
|
graph_add_edge(graph, 0, 1, 0);
|
||||||
|
graph_add_edge(graph, 0, 2, 0);
|
||||||
|
graph_add_edge(graph, 0, 3, 0);
|
||||||
|
graph_add_edge(graph, 1, 0, 0);
|
||||||
|
graph_add_edge(graph, 1, 2, 0);
|
||||||
|
graph_add_edge(graph, 1, 3, 0);
|
||||||
|
graph_add_edge(graph, 2, 3, 0);
|
||||||
|
|
||||||
|
graph_remove_vertex(graph, 1);
|
||||||
|
graph_remove_edge(graph, 0, 2);
|
||||||
|
|
||||||
|
graph_dfs(graph, 0, graph_traverse_int);
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
结果
|
||||||
|
```
|
||||||
|
graph[0] 100
|
||||||
|
graph[3] 500
|
||||||
|
```
|
||||||
|
|
||||||
|
### 遍历
|
||||||
|
|
||||||
|
```c
|
||||||
|
void graph_ls(graph_t graph, graph_traverse_t func);
|
||||||
|
```
|
||||||
|
|
||||||
|
从图开始位置逐个线性遍历。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向要遍历的图的指针。
|
||||||
|
- `func`: 对每个访问到的顶点执行的回调函数。
|
||||||
|
|
||||||
|
**返回**: 无
|
||||||
|
|
||||||
|
```c
|
||||||
|
void graph_ls(graph_t graph, graph_traverse_t func);
|
||||||
|
```
|
||||||
|
|
||||||
|
从指定起始顶点开始执行深度优先遍历。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向要遍历的图的指针。
|
||||||
|
- `start`: 起始顶点的索引。
|
||||||
|
- `func`: 对每个访问到的顶点执行的回调函数。
|
||||||
|
|
||||||
|
**返回**: 无
|
||||||
|
|
||||||
|
```c
|
||||||
|
void graph_dfs(graph_t graph, int start, graph_traverse_t func);
|
||||||
|
```
|
||||||
|
|
||||||
|
从指定起始顶点开始执行广度优先遍历。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向要遍历的图的指针。
|
||||||
|
- `start`: 起始顶点的索引。
|
||||||
|
- `func`: 对每个访问到的顶点执行的回调函数。
|
||||||
|
|
||||||
|
**返回**: 无
|
||||||
|
|
||||||
|
例子
|
||||||
|
```c
|
||||||
|
static void test_search(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(100, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 100), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 200), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 300), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 500), sizeof(int));
|
||||||
|
|
||||||
|
graph_add_edge(graph, 0, 1, 0);
|
||||||
|
graph_add_edge(graph, 0, 2, 0);
|
||||||
|
graph_add_edge(graph, 0, 3, 0);
|
||||||
|
graph_add_edge(graph, 1, 0, 0);
|
||||||
|
graph_add_edge(graph, 1, 2, 0);
|
||||||
|
graph_add_edge(graph, 1, 3, 0);
|
||||||
|
graph_add_edge(graph, 2, 3, 0);
|
||||||
|
|
||||||
|
graph_remove_vertex(graph, 1);
|
||||||
|
graph_remove_edge(graph, 0, 2);
|
||||||
|
|
||||||
|
printf("graph_ls ----------------------\r\n");
|
||||||
|
graph_ls(graph, graph_traverse_int);
|
||||||
|
printf("graph_dfs ----------------------\r\n");
|
||||||
|
graph_dfs(graph, 0, graph_traverse_int);
|
||||||
|
printf("graph_bfs ----------------------\r\n");
|
||||||
|
graph_bfs(graph, 0, graph_traverse_int);
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
结果
|
||||||
|
```
|
||||||
|
graph_ls ----------------------
|
||||||
|
graph[0] 100
|
||||||
|
graph[2] 300
|
||||||
|
graph[3] 500
|
||||||
|
graph_dfs ----------------------
|
||||||
|
graph[0] 100
|
||||||
|
graph[3] 500
|
||||||
|
graph_bfs ----------------------
|
||||||
|
graph[0] 100
|
||||||
|
graph[3] 500
|
||||||
|
```
|
||||||
|
|
||||||
|
### 设置和获取数据
|
||||||
|
|
||||||
|
```c
|
||||||
|
int graph_vertex_set_data(graph_t graph, int index, void *data, int size);
|
||||||
|
```
|
||||||
|
|
||||||
|
为图中的指定顶点设置数据。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向图的指针。
|
||||||
|
- `index`: 顶点的索引。
|
||||||
|
- `data`: 要设置的数据的指针。
|
||||||
|
- `size`: 数据的大小。
|
||||||
|
|
||||||
|
**返回**: 如果成功设置数据返回1,失败返回0。
|
||||||
|
|
||||||
|
```c
|
||||||
|
int graph_vertex_get_data(graph_t graph, int index, void *data, int size);
|
||||||
|
```
|
||||||
|
|
||||||
|
从图中的指定顶点获取数据。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向图的指针。
|
||||||
|
- `index`: 顶点的索引。
|
||||||
|
- `data`: 指向将要复制数据的位置的指针。
|
||||||
|
- `size`: 数据缓冲区的大小。
|
||||||
|
|
||||||
|
**返回**: 如果成功获取数据返回1,失败返回0。
|
||||||
|
|
||||||
|
```c
|
||||||
|
void *graph_vertex_data(graph_t graph, int index, int *size);
|
||||||
|
```
|
||||||
|
|
||||||
|
获取图中指定顶点的数据。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向图的指针。
|
||||||
|
- `index`: 顶点的索引。
|
||||||
|
- `size`: 指向存储顶点数据大小的指针(如果不为NULL)。
|
||||||
|
|
||||||
|
**返回**: 返回顶点数据的指针,如果失败则返回NULL。
|
||||||
|
|
||||||
|
例子
|
||||||
|
```c
|
||||||
|
static void test_data(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(100, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 100), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 200), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 300), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 500), sizeof(int));
|
||||||
|
|
||||||
|
graph_vertex_set_data(graph, 2, la(int, 1024), sizeof(int));
|
||||||
|
|
||||||
|
int size = 0;
|
||||||
|
printf("graph_vertex_data[3].data = %d\r\n", *(int *)graph_vertex_data(graph, 3, &size));
|
||||||
|
printf("graph_vertex_data[3].size = %d\r\n", size);
|
||||||
|
|
||||||
|
graph_ls(graph, graph_traverse_int);
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
结果
|
||||||
|
```
|
||||||
|
graph_vertex_data[3].data = 500
|
||||||
|
graph_vertex_data[3].size = 4
|
||||||
|
graph[0] 100
|
||||||
|
graph[1] 200
|
||||||
|
graph[2] 1024
|
||||||
|
graph[3] 500
|
||||||
|
```
|
||||||
|
|
||||||
|
### 出度和入度
|
||||||
|
|
||||||
|
```c
|
||||||
|
int graph_out_degree(graph_t graph, int index);
|
||||||
|
```
|
||||||
|
|
||||||
|
获取指定顶点的出度。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向图的指针。
|
||||||
|
- `index`: 顶点的索引。
|
||||||
|
|
||||||
|
**返回**: 顶点的出度,如果失败返回-1。
|
||||||
|
|
||||||
|
```c
|
||||||
|
int graph_in_degree(graph_t graph, int index);
|
||||||
|
```
|
||||||
|
|
||||||
|
获取指定顶点的入度。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向图的指针。
|
||||||
|
- `index`: 顶点的索引。
|
||||||
|
|
||||||
|
**返回**: 顶点的入度,如果失败返回-1。
|
||||||
|
|
||||||
|
例子
|
||||||
|
```c
|
||||||
|
static void test_degree(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(10, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 100), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 200), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 300), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 500), sizeof(int));
|
||||||
|
|
||||||
|
graph_add_edge(graph, 0, 1, 0);
|
||||||
|
graph_add_edge(graph, 0, 2, 0);
|
||||||
|
graph_add_edge(graph, 0, 3, 0);
|
||||||
|
graph_add_edge(graph, 1, 0, 0);
|
||||||
|
graph_add_edge(graph, 1, 2, 0);
|
||||||
|
graph_add_edge(graph, 1, 3, 0);
|
||||||
|
graph_add_edge(graph, 2, 3, 0);
|
||||||
|
|
||||||
|
printf("graph_out_degree %d\r\n", graph_out_degree(graph, 3));
|
||||||
|
printf("graph_out_degree %d\r\n", graph_out_degree(graph, 2));
|
||||||
|
|
||||||
|
printf("graph_in_degree %d\r\n", graph_in_degree(graph, 0));
|
||||||
|
printf("graph_in_degree %d\r\n", graph_in_degree(graph, 2));
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
结果
|
||||||
|
```
|
||||||
|
graph_out_degree 0
|
||||||
|
graph_out_degree 1
|
||||||
|
graph_in_degree 1
|
||||||
|
graph_in_degree 2
|
||||||
|
```
|
||||||
|
|
||||||
|
### 相邻
|
||||||
|
|
||||||
|
```c
|
||||||
|
int graph_is_adjacent(graph_t graph, int start, int end);
|
||||||
|
```
|
||||||
|
|
||||||
|
检查两个顶点是否相邻。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向图的指针。
|
||||||
|
- `start`: 起始顶点的索引。
|
||||||
|
- `end`: 结束顶点的索引。
|
||||||
|
|
||||||
|
**返回**: 。如果顶点相邻返回1,否则返回0或失败
|
||||||
|
|
||||||
|
|
||||||
|
### 权重
|
||||||
|
|
||||||
|
```c
|
||||||
|
int graph_get_edge_weight(graph_t graph, int start, int end);
|
||||||
|
```
|
||||||
|
|
||||||
|
获取两个顶点之间边的权重(如果存在)。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向图的指针。
|
||||||
|
- `start`: 起始顶点的索引。
|
||||||
|
- `end`: 结束顶点的索引。
|
||||||
|
|
||||||
|
**返回**: 边的权重,如果失败或边不存在返回INT_MAX。
|
||||||
|
|
||||||
|
```c
|
||||||
|
int graph_set_edge_weight(graph_t graph, int start, int end, int weight);
|
||||||
|
```
|
||||||
|
|
||||||
|
设置两个顶点之间边的权重(如果存在)。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向图的指针。
|
||||||
|
- `start`: 起始顶点的索引。
|
||||||
|
- `end`: 结束顶点的索引。
|
||||||
|
- `weight`: 边的权重。
|
||||||
|
|
||||||
|
**返回**: 如果存在该边返回1,否则返回0或失败。
|
||||||
|
|
||||||
|
例子
|
||||||
|
```c
|
||||||
|
static void test_weight(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(100, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 100), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 200), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 300), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 500), sizeof(int));
|
||||||
|
|
||||||
|
graph_add_edge(graph, 0, 1, 0);
|
||||||
|
graph_add_edge(graph, 0, 2, 0);
|
||||||
|
graph_add_edge(graph, 0, 3, 10);
|
||||||
|
graph_add_edge(graph, 1, 0, 0);
|
||||||
|
graph_add_edge(graph, 1, 2, 0);
|
||||||
|
graph_add_edge(graph, 1, 3, 0);
|
||||||
|
graph_add_edge(graph, 2, 3, 0);
|
||||||
|
|
||||||
|
printf("graph_get_edge_weight = %d\r\n", graph_get_edge_weight(graph, 0, 3));
|
||||||
|
graph_set_edge_weight(graph, 0, 3, 1024);
|
||||||
|
printf("graph_get_edge_weight = %d\r\n", graph_get_edge_weight(graph, 0, 3));
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
结果
|
||||||
|
```
|
||||||
|
graph_get_edge_weight = 10
|
||||||
|
graph_get_edge_weight = 1024
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### 检查顶点
|
||||||
|
|
||||||
|
```c
|
||||||
|
int graph_contains_vertex(graph_t graph, int index);
|
||||||
|
```
|
||||||
|
|
||||||
|
检查顶点是否存在于图中。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向图的指针。
|
||||||
|
- `index`: 顶点的索引。
|
||||||
|
|
||||||
|
**返回**: 如果顶点存在返回1,否则返回0或失败。
|
||||||
|
|
||||||
|
|
||||||
|
### 拓扑排序
|
||||||
|
|
||||||
|
```c
|
||||||
|
int graph_contains_vertex(graph_t graph, int index);
|
||||||
|
```
|
||||||
|
|
||||||
|
对图进行拓扑排序。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向图的指针。
|
||||||
|
|
||||||
|
**返回**: 无
|
||||||
|
|
||||||
|
|
||||||
|
### 最短路径
|
||||||
|
|
||||||
|
```c
|
||||||
|
void graph_shortest_path(graph_t graph, int start);
|
||||||
|
```
|
||||||
|
|
||||||
|
查找从起始顶点到其它顶点的最短路径。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向图的指针。
|
||||||
|
- `start`: 起始顶点的索引。
|
||||||
|
|
||||||
|
**返回**: 无
|
||||||
|
|
||||||
|
例子
|
||||||
|
```c
|
||||||
|
static void test_shortest_path(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(100, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 100), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 200), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 300), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 500), sizeof(int));
|
||||||
|
|
||||||
|
graph_add_edge(graph, 0, 1, 3);
|
||||||
|
graph_add_edge(graph, 0, 2, 2);
|
||||||
|
graph_add_edge(graph, 0, 3, 5);
|
||||||
|
graph_add_edge(graph, 1, 0, 6);
|
||||||
|
graph_add_edge(graph, 1, 2, 3);
|
||||||
|
graph_add_edge(graph, 1, 3, 2);
|
||||||
|
graph_add_edge(graph, 2, 3, 1);
|
||||||
|
|
||||||
|
graph_shortest_path(graph, 0);
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
结果
|
||||||
|
```
|
||||||
|
Shortest path from 0 to 0: 0 (0)
|
||||||
|
Shortest path from 0 to 1: 3 (0 -> 1)
|
||||||
|
Shortest path from 0 to 2: 2 (0 -> 2)
|
||||||
|
Shortest path from 0 to 3: 3 (0 -> 2 -> 3)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 连通图
|
||||||
|
|
||||||
|
```c
|
||||||
|
int graph_is_connected(graph_t graph);
|
||||||
|
```
|
||||||
|
|
||||||
|
检查图是否连通。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向图的指针。
|
||||||
|
|
||||||
|
**返回**: 如果图连通返回1,否则返回0。
|
||||||
|
|
||||||
|
|
||||||
|
### 完全图
|
||||||
|
|
||||||
|
```c
|
||||||
|
int graph_is_complete(graph_t graph);
|
||||||
|
```
|
||||||
|
|
||||||
|
检查图是否为完全图。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向图的指针。
|
||||||
|
|
||||||
|
**返回**: 如果图为完全图返回1,否则返回0。
|
||||||
|
|
||||||
|
### 二部图
|
||||||
|
|
||||||
|
```c
|
||||||
|
int graph_is_bipartite(graph_t graph);
|
||||||
|
```
|
||||||
|
|
||||||
|
检查图是否为二部图。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向图的指针。
|
||||||
|
|
||||||
|
**返回**: 如果图为二部图返回1,否则返回0。
|
||||||
|
|
||||||
|
### 欧拉图
|
||||||
|
|
||||||
|
```c
|
||||||
|
int graph_is_eulerian(graph_t graph);
|
||||||
|
```
|
||||||
|
|
||||||
|
检查图是否为欧拉图(能恰好遍历每条边一次)。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向图的指针。
|
||||||
|
|
||||||
|
**返回**: 如果图为欧拉图返回1,否则返回0。
|
||||||
|
|
||||||
|
### 最小顶点覆盖
|
||||||
|
|
||||||
|
```c
|
||||||
|
void graph_min_vertex_cover(graph_t graph);
|
||||||
|
```
|
||||||
|
|
||||||
|
计算图的最小顶点覆盖。
|
||||||
|
|
||||||
|
**参数**:
|
||||||
|
- `graph`: 指向图的指针。
|
||||||
|
|
||||||
|
**返回**: 无
|
||||||
|
|
||||||
|
例子
|
||||||
|
```c
|
||||||
|
static void test_min_cover(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(100, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 100), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 200), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 300), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 500), sizeof(int));
|
||||||
|
|
||||||
|
graph_add_edge(graph, 0, 1, 3);
|
||||||
|
graph_add_edge(graph, 0, 2, 2);
|
||||||
|
graph_add_edge(graph, 0, 3, 5);
|
||||||
|
graph_add_edge(graph, 1, 0, 6);
|
||||||
|
graph_add_edge(graph, 1, 2, 3);
|
||||||
|
graph_add_edge(graph, 1, 3, 2);
|
||||||
|
graph_add_edge(graph, 2, 3, 1);
|
||||||
|
|
||||||
|
graph_min_vertex_cover(graph);
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
结果
|
||||||
|
```
|
||||||
|
0 3 1 2
|
||||||
|
```
|
||||||
59
makefile
59
makefile
@ -20,6 +20,8 @@ PARSER_PATH = $(WORKSPACE)/05_parser
|
|||||||
##################################################################################
|
##################################################################################
|
||||||
### sources and head path
|
### sources and head path
|
||||||
##################################################################################
|
##################################################################################
|
||||||
|
include $(TESTSPACE)/test.mk
|
||||||
|
|
||||||
INCLUDE += -I $(APPLICATION_PATH)
|
INCLUDE += -I $(APPLICATION_PATH)
|
||||||
INCLUDE += -I $(GENDATA_PATH)
|
INCLUDE += -I $(GENDATA_PATH)
|
||||||
INCLUDE += -I $(VSTD_PATH)
|
INCLUDE += -I $(VSTD_PATH)
|
||||||
@ -35,66 +37,27 @@ SOURCES += $(wildcard $(VSTD_PATH)/*.c)
|
|||||||
SOURCES += $(wildcard $(CONTAINER_PATH)/*.c)
|
SOURCES += $(wildcard $(CONTAINER_PATH)/*.c)
|
||||||
SOURCES += $(wildcard $(ALGORITHM_PATH)/*.c)
|
SOURCES += $(wildcard $(ALGORITHM_PATH)/*.c)
|
||||||
SOURCES += $(wildcard $(PARSER_PATH)/*.c)
|
SOURCES += $(wildcard $(PARSER_PATH)/*.c)
|
||||||
|
SOURCES += $(TEST_SRC)
|
||||||
#----------------------------------------
|
|
||||||
# test sources
|
|
||||||
#----------------------------------------
|
|
||||||
# SOURCES += $(TESTSPACE)/test_init.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_kern.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_valloc.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_arg.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_vstd.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_vlog.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_ini.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_txls.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_xml.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_csv.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_json.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_vector.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_list.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_str.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_queue.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_stack.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_deque.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_set.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_dict.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_map.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_heap.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_tree.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_rbtree.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_pthread.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_encrypt.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_calculate.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_command.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_check.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_crc.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_sort.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_hash.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_pid.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_search.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_filter.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_oscp.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_tool.c
|
|
||||||
SOURCES += $(TESTSPACE)/test_sList.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_dList.c
|
|
||||||
# SOURCES += $(TESTSPACE)/test_cQueue.c
|
|
||||||
|
|
||||||
##################################################################################
|
##################################################################################
|
||||||
### targets and recipes
|
### targets and recipes
|
||||||
##################################################################################
|
##################################################################################
|
||||||
OBJS = $(patsubst %.c, $(BUILT_DIR)/%.o, $(SOURCES))
|
OBJ_PATH = $(BUILT_DIR)/obj
|
||||||
TAR_PATH = $(BUILT_DIR)/$(TARGET)
|
BIN_PATH = $(BUILT_DIR)/bin
|
||||||
|
OBJS = $(patsubst %.c, $(OBJ_PATH)/%.o, $(SOURCES))
|
||||||
|
TAR_PATH = $(BIN_PATH)/$(TARGET)
|
||||||
|
|
||||||
# link
|
# link
|
||||||
${TAR_PATH}:$(OBJS)
|
${TAR_PATH}:$(OBJS)
|
||||||
|
$(shell mkdir -p $(dir $@))
|
||||||
# @ $(CC) $(OBJS) -o $(TAR_PATH) -lm -lX11 -lpthread
|
# @ $(CC) $(OBJS) -o $(TAR_PATH) -lm -lX11 -lpthread
|
||||||
@ $(CC) $(OBJS) -o $(TAR_PATH) -lm -lpthread
|
@ $(CC) $(CFLAG) $(OBJS) -o $(TAR_PATH) -lm -lpthread
|
||||||
|
|
||||||
# compile
|
# compile
|
||||||
$(BUILT_DIR)/%.o:%.c
|
$(OBJ_PATH)/%.o:%.c
|
||||||
$(shell mkdir -p $(dir $@))
|
$(shell mkdir -p $(dir $@))
|
||||||
@ echo "compiling $(notdir $<)"
|
@ echo "compiling $(notdir $<)"
|
||||||
@ $(CC) $(INCLUDE) -c $< -o $@
|
@ $(CC) $(CFLAG) $(INCLUDE) -c $< -o $@
|
||||||
|
|
||||||
.PHONY:clean
|
.PHONY:clean
|
||||||
clean:
|
clean:
|
||||||
|
|||||||
2
run.sh
2
run.sh
@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
exe_file="built/app"
|
exe_file="built/bin/app"
|
||||||
|
|
||||||
echo "cleaning..."
|
echo "cleaning..."
|
||||||
if [ -f $exe_file ]; then
|
if [ -f $exe_file ]; then
|
||||||
|
|||||||
1327
source/03_container/graph.c
Normal file
1327
source/03_container/graph.c
Normal file
File diff suppressed because it is too large
Load Diff
238
source/03_container/graph.h
Normal file
238
source/03_container/graph.h
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
/*********************************************************************************************************
|
||||||
|
* ------------------------------------------------------------------------------------------------------
|
||||||
|
* file description
|
||||||
|
* ------------------------------------------------------------------------------------------------------
|
||||||
|
* \file graph.h
|
||||||
|
* \unit graph
|
||||||
|
* \brief This is a C language graph
|
||||||
|
* \author Lamdonn
|
||||||
|
* \version v1.0.0
|
||||||
|
* \license GPL-2.0
|
||||||
|
* \copyright Copyright (C) 2023 Lamdonn.
|
||||||
|
********************************************************************************************************/
|
||||||
|
#ifndef __graph_H
|
||||||
|
#define __graph_H
|
||||||
|
|
||||||
|
/* Version infomation */
|
||||||
|
#define GRAPH_V_MAJOR 1
|
||||||
|
#define GRAPH_V_MINOR 0
|
||||||
|
#define GRAPH_V_PATCH 0
|
||||||
|
|
||||||
|
/* graph type definition, hiding structural members, not for external use */
|
||||||
|
|
||||||
|
typedef struct GRAPH *graph_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief traverse callback function type
|
||||||
|
* \param[in] index: vertex index
|
||||||
|
* \param[in] data: address of data
|
||||||
|
* \param[in] size: size of data
|
||||||
|
* \return none
|
||||||
|
*/
|
||||||
|
typedef void (*graph_traverse_t)(int index, void *data, int size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Creates and initializes a graph
|
||||||
|
* \param[in] max: maximum number of vertices in the graph
|
||||||
|
* \param[in] directed: flag indicating if the graph is directed (non-zero) or undirected (zero)
|
||||||
|
* \return A pointer to the newly created graph, or NULL if creation fails
|
||||||
|
*/
|
||||||
|
graph_t graph_create(int max, int directed);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Destroys a graph and frees associated resources
|
||||||
|
* \param[in] graph: pointer to the graph to be destroyed
|
||||||
|
* \return none
|
||||||
|
*/
|
||||||
|
void graph_delete(graph_t graph);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Adds a vertex to the graph
|
||||||
|
* \param[in] graph: pointer to the graph to which the vertex will be added
|
||||||
|
* \param[in] data: pointer to the data associated with the vertex
|
||||||
|
* \param[in] size: size of the data to be copied
|
||||||
|
* \return The index of the added vertex, or -1 if the addition fails
|
||||||
|
*/
|
||||||
|
int graph_add_vertex(graph_t graph, void *data, int size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Adds an edge to the graph
|
||||||
|
* \param[in] graph: pointer to the graph where the edge will be added
|
||||||
|
* \param[in] start: index of the starting vertex
|
||||||
|
* \param[in] end: index of the ending vertex
|
||||||
|
* \param[in] weight: weight of the edge
|
||||||
|
* \return 1 if the edge was added successfully, 0 if the addition fails
|
||||||
|
*/
|
||||||
|
int graph_add_edge(graph_t graph, int start, int end, int weight);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Removes a specified vertex and its associated edges from the graph
|
||||||
|
* \param[in] graph: pointer to the graph from which the vertex will be removed
|
||||||
|
* \param[in] index: index of the vertex to be removed
|
||||||
|
* \return 1 if the vertex was removed successfully, 0 if the removal fails
|
||||||
|
*/
|
||||||
|
int graph_remove_vertex(graph_t graph, int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Removes a specified edge from the graph
|
||||||
|
* \param[in] graph: pointer to the graph from which the edge will be removed
|
||||||
|
* \param[in] start: index of the starting vertex of the edge
|
||||||
|
* \param[in] end: index of the ending vertex of the edge
|
||||||
|
* \return 1 if the edge was removed successfully, 0 if the removal fails
|
||||||
|
*/
|
||||||
|
int graph_remove_edge(graph_t graph, int start, int end);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Performs a linear search on the graph and applies the provided function to each vertex
|
||||||
|
* \param[in] graph: pointer to the graph
|
||||||
|
* \param[in] func: function to apply to each vertex (takes vertex index, data, and size)
|
||||||
|
*/
|
||||||
|
void graph_ls(graph_t graph, graph_traverse_t func);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initiates a DFS traversal from a specified starting vertex
|
||||||
|
* \param[in] graph: pointer to the graph to be traversed
|
||||||
|
* \param[in] start: index of the starting vertex
|
||||||
|
* \param[in] func: callback function to be executed for each visited vertex
|
||||||
|
* \return none
|
||||||
|
*/
|
||||||
|
void graph_dfs(graph_t graph, int start, graph_traverse_t func);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initiates a BFS traversal from a specified starting vertex
|
||||||
|
* \param[in] graph: pointer to the graph to be traversed
|
||||||
|
* \param[in] start: index of the starting vertex
|
||||||
|
* \param[in] func: callback function to be executed for each visited vertex
|
||||||
|
* \return none
|
||||||
|
*/
|
||||||
|
void graph_bfs(graph_t graph, int start, graph_traverse_t func);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sets data for a specified vertex in the graph
|
||||||
|
* \param[in] graph: pointer to the graph
|
||||||
|
* \param[in] index: index of the vertex
|
||||||
|
* \param[in] data: pointer to the data to be set
|
||||||
|
* \param[in] size: size of the data
|
||||||
|
* \return 1 if the data was set successfully, 0 if it fails
|
||||||
|
*/
|
||||||
|
int graph_vertex_set_data(graph_t graph, int index, void *data, int size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves data from a specified vertex in the graph
|
||||||
|
* \param[in] graph: pointer to the graph
|
||||||
|
* \param[in] index: index of the vertex
|
||||||
|
* \param[out] data: pointer to where the data will be copied
|
||||||
|
* \param[in] size: size of the buffer for data
|
||||||
|
* \return 1 if the data was retrieved successfully, 0 if it fails
|
||||||
|
*/
|
||||||
|
int graph_vertex_get_data(graph_t graph, int index, void *data, int size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the data of a specified vertex in the graph
|
||||||
|
* \param[in] graph: pointer to the graph
|
||||||
|
* \param[in] index: index of the vertex
|
||||||
|
* \param[out] size: pointer to store the size of the vertex data (if not NULL)
|
||||||
|
* \return Pointer to the vertex data, or NULL if it fails
|
||||||
|
*/
|
||||||
|
void *graph_vertex_data(graph_t graph, int index, int *size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the out-degree of a specified vertex in a directed graph
|
||||||
|
* \param[in] graph: pointer to the graph
|
||||||
|
* \param[in] index: index of the vertex
|
||||||
|
* \return The out-degree of the vertex, or -1 if it fails
|
||||||
|
*/
|
||||||
|
int graph_out_degree(graph_t graph, int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the in-degree of a specified vertex in a directed graph
|
||||||
|
* \param[in] graph: pointer to the graph
|
||||||
|
* \param[in] index: index of the vertex
|
||||||
|
* \return The in-degree of the vertex, or -1 if it fails
|
||||||
|
*/
|
||||||
|
int graph_in_degree(graph_t graph, int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Checks if two vertices are adjacent in the graph
|
||||||
|
* \param[in] graph: pointer to the graph
|
||||||
|
* \param[in] start: index of the starting vertex
|
||||||
|
* \param[in] end: index of the ending vertex
|
||||||
|
* \return 1 if the vertices are adjacent, 0 if they are not or if it fails
|
||||||
|
*/
|
||||||
|
int graph_is_adjacent(graph_t graph, int start, int end);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves the weight of the edge between two vertices in a weighted graph
|
||||||
|
* \param[in] graph: pointer to the graph
|
||||||
|
* \param[in] start: index of the starting vertex
|
||||||
|
* \param[in] end: index of the ending vertex
|
||||||
|
* \return The weight of the edge if it exists, or INT_MAX if it fails or the edge does not exist
|
||||||
|
*/
|
||||||
|
int graph_get_edge_weight(graph_t graph, int start, int end);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sets the weight of the edge between two vertices in a weighted graph
|
||||||
|
* \param[in] graph: pointer to the graph
|
||||||
|
* \param[in] start: index of the starting vertex
|
||||||
|
* \param[in] end: index of the ending vertex
|
||||||
|
* \param[in] weight: new weight for the edge
|
||||||
|
* \return 1 if the weight was set successfully, 0 if it fails
|
||||||
|
*/
|
||||||
|
int graph_set_edge_weight(graph_t graph, int start, int end, int weight);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Checks if a vertex exists in the graph
|
||||||
|
* \param[in] graph: pointer to the graph
|
||||||
|
* \param[in] index: index of the vertex
|
||||||
|
* \return 1 if the vertex exists, 0 if it does not or if it fails
|
||||||
|
*/
|
||||||
|
int graph_contains_vertex(graph_t graph, int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Public function to perform topological sort on the graph
|
||||||
|
* \param[in] graph: pointer to the graph
|
||||||
|
*/
|
||||||
|
void graph_topological_sort(graph_t graph);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Public function to find shortest paths from a starting vertex in the graph
|
||||||
|
* \param[in] graph: pointer to the graph
|
||||||
|
* \param[in] start: index of the starting vertex
|
||||||
|
*/
|
||||||
|
void graph_shortest_path(graph_t graph, int start);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Checks if the graph is connected
|
||||||
|
* \param[in] graph: pointer to the graph
|
||||||
|
* \return 1 if the graph is connected, 0 if it is not
|
||||||
|
*/
|
||||||
|
int graph_is_connected(graph_t graph);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Public function to determine if the graph is a complete graph
|
||||||
|
* \param[in] graph: pointer to the graph
|
||||||
|
* \return 1 if the graph is complete, 0 if it is not
|
||||||
|
*/
|
||||||
|
int graph_is_complete(graph_t graph);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Public function to determine if the graph is bipartite
|
||||||
|
* \param[in] graph: pointer to the graph
|
||||||
|
* \return 1 if the graph is bipartite, 0 if it is not
|
||||||
|
*/
|
||||||
|
int graph_is_bipartite(graph_t graph);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Checks if the graph is Eulerian (can traverse each edge exactly once)
|
||||||
|
* \param[in] graph: pointer to the graph
|
||||||
|
* \return 1 if the graph is Eulerian, 0 if it is not
|
||||||
|
*/
|
||||||
|
int graph_is_eulerian(graph_t graph);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Public function to compute the minimum vertex cover for the graph
|
||||||
|
* \param[in] graph: pointer to the graph
|
||||||
|
*/
|
||||||
|
void graph_min_vertex_cover(graph_t graph);
|
||||||
|
|
||||||
|
#endif
|
||||||
49
test/test.mk
Normal file
49
test/test.mk
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
TEST_SRC =
|
||||||
|
TEST_INC =
|
||||||
|
|
||||||
|
#----------------------------------------
|
||||||
|
# test sources
|
||||||
|
#----------------------------------------
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_init.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_kern.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_valloc.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_arg.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_vstd.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_vlog.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_ini.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_txls.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_xml.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_csv.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_json.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_vector.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_list.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_str.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_queue.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_stack.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_deque.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_set.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_dict.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_map.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_heap.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_tree.c
|
||||||
|
TEST_SRC += $(TESTSPACE)/test_graph.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_rbtree.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_pthread.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_encrypt.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_calculate.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_command.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_check.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_crc.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_sort.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_hash.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_pid.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_search.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_filter.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_oscp.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_tool.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_sList.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_dList.c
|
||||||
|
# TEST_SRC += $(TESTSPACE)/test_cQueue.c
|
||||||
|
|
||||||
|
export TEST_SRC TEST_INC
|
||||||
384
test/test_graph.c
Normal file
384
test/test_graph.c
Normal file
@ -0,0 +1,384 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "init.h"
|
||||||
|
#include "tool.h"
|
||||||
|
#include "valloc.h"
|
||||||
|
#include "graph.h"
|
||||||
|
#include "arg.h"
|
||||||
|
|
||||||
|
#define la(type, value) ((type[1]){value})
|
||||||
|
|
||||||
|
void graph_traverse_int(int index, void *data, int size)
|
||||||
|
{
|
||||||
|
printf("graph[%d] %d\r\n", index, *(int *)data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_create(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
int i = 25;
|
||||||
|
int index = -1;
|
||||||
|
|
||||||
|
graph = graph_create(100, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
index = graph_add_vertex(graph, la(int, 12), sizeof(int));
|
||||||
|
printf("index %d\r\n", index);
|
||||||
|
|
||||||
|
index = graph_add_vertex(graph, la(int, 13), sizeof(int));
|
||||||
|
printf("index %d\r\n", index);
|
||||||
|
|
||||||
|
index = graph_add_vertex(graph, la(int, 15), sizeof(int));
|
||||||
|
printf("index %d\r\n", index);
|
||||||
|
|
||||||
|
index = graph_add_vertex(graph, la(int, 23), sizeof(int));
|
||||||
|
printf("index %d\r\n", index);
|
||||||
|
|
||||||
|
printf("graph_add_edge %d\r\n", graph_add_edge(graph, 0, 1, 0));
|
||||||
|
printf("graph_add_edge %d\r\n", graph_add_edge(graph, 0, 2, 0));
|
||||||
|
printf("graph_add_edge %d\r\n", graph_add_edge(graph, 2, 3, 0));
|
||||||
|
|
||||||
|
// graph_remove_edge(graph, 0, 2);
|
||||||
|
// graph_remove_vertex(graph, 0);
|
||||||
|
|
||||||
|
printf("ret %d\r\n", graph_vertex_set_data(graph, 1, la(int, 1024), sizeof(int)));
|
||||||
|
|
||||||
|
printf("graph_vertex_data %d\r\n", *(int *)graph_vertex_data(graph, 1, NULL));
|
||||||
|
|
||||||
|
graph_dfs(graph, 0, graph_traverse_int);
|
||||||
|
printf("----------------------\r\n");
|
||||||
|
graph_bfs(graph, 0, graph_traverse_int);
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_add_vertex(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(10, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 12), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 13), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 15), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 23), sizeof(int));
|
||||||
|
|
||||||
|
graph_ls(graph, graph_traverse_int);
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_add_edge(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(10, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 12), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 13), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 15), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 23), sizeof(int));
|
||||||
|
|
||||||
|
printf("---------------\r\n");
|
||||||
|
|
||||||
|
graph_dfs(graph, 0, graph_traverse_int);
|
||||||
|
|
||||||
|
printf("---------------\r\n");
|
||||||
|
|
||||||
|
graph_add_edge(graph, 0, 1, 0);
|
||||||
|
graph_add_edge(graph, 0, 2, 0);
|
||||||
|
graph_add_edge(graph, 0, 3, 0);
|
||||||
|
graph_add_edge(graph, 1, 0, 0);
|
||||||
|
graph_add_edge(graph, 1, 2, 0);
|
||||||
|
graph_add_edge(graph, 1, 3, 0);
|
||||||
|
graph_add_edge(graph, 2, 3, 0);
|
||||||
|
|
||||||
|
graph_dfs(graph, 0, graph_traverse_int);
|
||||||
|
|
||||||
|
printf("---------------\r\n");
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_degree(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(10, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 100), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 200), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 300), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 500), sizeof(int));
|
||||||
|
|
||||||
|
graph_add_edge(graph, 0, 1, 0);
|
||||||
|
graph_add_edge(graph, 0, 2, 0);
|
||||||
|
graph_add_edge(graph, 0, 3, 0);
|
||||||
|
graph_add_edge(graph, 1, 0, 0);
|
||||||
|
graph_add_edge(graph, 1, 2, 0);
|
||||||
|
graph_add_edge(graph, 1, 3, 0);
|
||||||
|
graph_add_edge(graph, 2, 3, 0);
|
||||||
|
|
||||||
|
printf("graph_out_degree %d\r\n", graph_out_degree(graph, 3));
|
||||||
|
printf("graph_out_degree %d\r\n", graph_out_degree(graph, 2));
|
||||||
|
|
||||||
|
printf("graph_in_degree %d\r\n", graph_in_degree(graph, 0));
|
||||||
|
printf("graph_in_degree %d\r\n", graph_in_degree(graph, 2));
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_remove(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(100, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 100), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 200), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 300), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 500), sizeof(int));
|
||||||
|
|
||||||
|
graph_add_edge(graph, 0, 1, 0);
|
||||||
|
graph_add_edge(graph, 0, 2, 0);
|
||||||
|
graph_add_edge(graph, 0, 3, 0);
|
||||||
|
graph_add_edge(graph, 1, 0, 0);
|
||||||
|
graph_add_edge(graph, 1, 2, 0);
|
||||||
|
graph_add_edge(graph, 1, 3, 0);
|
||||||
|
graph_add_edge(graph, 2, 3, 0);
|
||||||
|
|
||||||
|
graph_remove_vertex(graph, 1);
|
||||||
|
graph_remove_edge(graph, 0, 2);
|
||||||
|
|
||||||
|
graph_dfs(graph, 0, graph_traverse_int);
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_search(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(100, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 100), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 200), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 300), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 500), sizeof(int));
|
||||||
|
|
||||||
|
graph_add_edge(graph, 0, 1, 0);
|
||||||
|
graph_add_edge(graph, 0, 2, 0);
|
||||||
|
graph_add_edge(graph, 0, 3, 0);
|
||||||
|
graph_add_edge(graph, 1, 0, 0);
|
||||||
|
graph_add_edge(graph, 1, 2, 0);
|
||||||
|
graph_add_edge(graph, 1, 3, 0);
|
||||||
|
graph_add_edge(graph, 2, 3, 0);
|
||||||
|
|
||||||
|
graph_remove_vertex(graph, 1);
|
||||||
|
graph_remove_edge(graph, 0, 2);
|
||||||
|
|
||||||
|
printf("graph_ls ----------------------\r\n");
|
||||||
|
graph_ls(graph, graph_traverse_int);
|
||||||
|
printf("graph_dfs ----------------------\r\n");
|
||||||
|
graph_dfs(graph, 0, graph_traverse_int);
|
||||||
|
printf("graph_bfs ----------------------\r\n");
|
||||||
|
graph_bfs(graph, 0, graph_traverse_int);
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_data(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(100, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 100), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 200), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 300), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 500), sizeof(int));
|
||||||
|
|
||||||
|
graph_vertex_set_data(graph, 2, la(int, 1024), sizeof(int));
|
||||||
|
|
||||||
|
int size = 0;
|
||||||
|
printf("graph_vertex_data[3].data = %d\r\n", *(int *)graph_vertex_data(graph, 3, &size));
|
||||||
|
printf("graph_vertex_data[3].size = %d\r\n", size);
|
||||||
|
|
||||||
|
graph_ls(graph, graph_traverse_int);
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_weight(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(100, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 100), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 200), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 300), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 500), sizeof(int));
|
||||||
|
|
||||||
|
graph_add_edge(graph, 0, 1, 0);
|
||||||
|
graph_add_edge(graph, 0, 2, 0);
|
||||||
|
graph_add_edge(graph, 0, 3, 10);
|
||||||
|
graph_add_edge(graph, 1, 0, 0);
|
||||||
|
graph_add_edge(graph, 1, 2, 0);
|
||||||
|
graph_add_edge(graph, 1, 3, 0);
|
||||||
|
graph_add_edge(graph, 2, 3, 0);
|
||||||
|
|
||||||
|
printf("graph_get_edge_weight = %d\r\n", graph_get_edge_weight(graph, 0, 3));
|
||||||
|
graph_set_edge_weight(graph, 0, 3, 1024);
|
||||||
|
printf("graph_get_edge_weight = %d\r\n", graph_get_edge_weight(graph, 0, 3));
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_shortest_path(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(100, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 100), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 200), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 300), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 500), sizeof(int));
|
||||||
|
|
||||||
|
graph_add_edge(graph, 0, 1, 3);
|
||||||
|
graph_add_edge(graph, 0, 2, 2);
|
||||||
|
graph_add_edge(graph, 0, 3, 5);
|
||||||
|
graph_add_edge(graph, 1, 0, 6);
|
||||||
|
graph_add_edge(graph, 1, 2, 3);
|
||||||
|
graph_add_edge(graph, 1, 3, 2);
|
||||||
|
graph_add_edge(graph, 2, 3, 1);
|
||||||
|
|
||||||
|
graph_shortest_path(graph, 0);
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_min_cover(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(100, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 100), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 200), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 300), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 500), sizeof(int));
|
||||||
|
|
||||||
|
graph_add_edge(graph, 0, 1, 3);
|
||||||
|
graph_add_edge(graph, 0, 2, 2);
|
||||||
|
graph_add_edge(graph, 0, 3, 5);
|
||||||
|
graph_add_edge(graph, 1, 0, 6);
|
||||||
|
graph_add_edge(graph, 1, 2, 3);
|
||||||
|
graph_add_edge(graph, 1, 3, 2);
|
||||||
|
graph_add_edge(graph, 2, 3, 1);
|
||||||
|
|
||||||
|
graph_min_vertex_cover(graph);
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_others(void)
|
||||||
|
{
|
||||||
|
graph_t graph = NULL;
|
||||||
|
|
||||||
|
graph = graph_create(100, 1);
|
||||||
|
if (!graph)
|
||||||
|
{
|
||||||
|
printf("graph_create fail!\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
graph_add_vertex(graph, la(int, 100), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 200), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 300), sizeof(int));
|
||||||
|
graph_add_vertex(graph, la(int, 500), sizeof(int));
|
||||||
|
|
||||||
|
graph_add_edge(graph, 0, 1, 3);
|
||||||
|
graph_add_edge(graph, 0, 2, 2);
|
||||||
|
graph_add_edge(graph, 0, 3, 5);
|
||||||
|
graph_add_edge(graph, 1, 0, 6);
|
||||||
|
graph_add_edge(graph, 1, 2, 3);
|
||||||
|
graph_add_edge(graph, 1, 3, 2);
|
||||||
|
graph_add_edge(graph, 2, 3, 1);
|
||||||
|
|
||||||
|
// graph_topological_sort(graph);
|
||||||
|
// graph_shortest_path(graph, 0);
|
||||||
|
// graph_minimum_spanning_tree(graph);
|
||||||
|
// printf("graph_is_connected %d\r\n", graph_is_connected(graph));
|
||||||
|
// printf("graph_is_complete %d\r\n", graph_is_complete(graph));
|
||||||
|
// printf("graph_is_bipartite %d\r\n", graph_is_bipartite(graph));
|
||||||
|
// printf("graph_is_eulerian %d\r\n", graph_is_eulerian(graph));
|
||||||
|
// printf("graph_is_eulerian %d\r\n", graph_max_flow(graph, 0, 3));
|
||||||
|
// graph_articulation_points(graph);
|
||||||
|
// graph_bridges(graph);
|
||||||
|
graph_min_vertex_cover(graph);
|
||||||
|
|
||||||
|
graph_dfs(graph, 0, graph_traverse_int);
|
||||||
|
|
||||||
|
graph_delete(graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test(void)
|
||||||
|
{
|
||||||
|
printf("graph test!\r\n");
|
||||||
|
|
||||||
|
// test_create();
|
||||||
|
// test_add_vertex();
|
||||||
|
// test_add_edge();
|
||||||
|
// test_remove();
|
||||||
|
// test_search();
|
||||||
|
// test_data();
|
||||||
|
// test_degree();
|
||||||
|
// test_weight();
|
||||||
|
// test_shortest_path();
|
||||||
|
test_min_cover();
|
||||||
|
|
||||||
|
v_check_unfree();
|
||||||
|
}
|
||||||
|
init_export_app(test);
|
||||||
Loading…
x
Reference in New Issue
Block a user