add graph, add windows vscode debug config

This commit is contained in:
Lamdonn 2024-08-11 02:56:16 +08:00
parent c91eabcb57
commit a390743342
16 changed files with 2905 additions and 53 deletions

2
.gitignore vendored
View File

@ -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
View 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
View 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
View File

@ -0,0 +1,5 @@
{
"files.associations": {
"init.h": "c"
}
}

30
.vscode/tasks.json vendored Normal file
View 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"
}

View File

@ -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

View File

@ -13,7 +13,7 @@ varchwe-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 @@ varchwe-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
View 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"

7
clean.sh Normal file
View File

@ -0,0 +1,7 @@
#!/bin/bash
echo "cleaning all ..."
rm built/* -rf

764
doc/graph.md Normal file
View 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
```

View File

@ -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
View File

@ -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

File diff suppressed because it is too large Load Diff

238
source/03_container/graph.h Normal file
View 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
View 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
View 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);