add: data-structure-lab & compiler-lab
This commit is contained in:
3
maze/.gitignore
vendored
Normal file
3
maze/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
cmake-build-*/
|
||||
build/
|
||||
.idea/
|
10
maze/CMakeLists.txt
Normal file
10
maze/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(maze)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR}/include)
|
||||
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/src SRCS)
|
||||
|
||||
add_executable(maze main.cpp ${SRCS})
|
71
maze/include/maze_node.h
Normal file
71
maze/include/maze_node.h
Normal file
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// Created by ricardo on 2022/10/25.
|
||||
//
|
||||
|
||||
#ifndef MAZE_MAZE_NODE_H
|
||||
#define MAZE_MAZE_NODE_H
|
||||
|
||||
// 全局的节点总数变量
|
||||
// 虽然全局变量有点不好
|
||||
extern int node_number;
|
||||
|
||||
struct maze_connect_node
|
||||
{
|
||||
// 连接的节点数组索引
|
||||
int index;
|
||||
struct maze_connect_node* next;
|
||||
};
|
||||
|
||||
typedef struct maze_connect_node maze_connect_node_t;
|
||||
typedef struct maze_connect_node* maze_connect_node_p;
|
||||
|
||||
struct maze_node
|
||||
{
|
||||
// 迷宫中结点的编号
|
||||
int id;
|
||||
// 与这个节点相连的节点链表
|
||||
maze_connect_node_p connect_maze_nodes;
|
||||
// 当前正在遍历的节点
|
||||
maze_connect_node_p now_node;
|
||||
};
|
||||
|
||||
// 迷宫节点结构体
|
||||
typedef struct maze_node maze_node_t;
|
||||
// 迷宫节点结构体指针
|
||||
typedef struct maze_node* maze_node_p;
|
||||
|
||||
/**
|
||||
* 创建迷宫节点数组
|
||||
* @param num 迷宫中节点的数量
|
||||
* @return 数组地址
|
||||
*/
|
||||
maze_node_p create_maze_node_array(int num);
|
||||
|
||||
/**
|
||||
* 在指定的节点中添加与之相连的节点
|
||||
* @param node 指定的节点引用
|
||||
* @param target 与之相连的节点
|
||||
* @return 是否添加成功
|
||||
*/
|
||||
bool maze_node_add_connect_node(maze_node_t& node, int target);
|
||||
|
||||
/**
|
||||
* 读取迷宫配置文件
|
||||
* @param filename 配置文件文件名
|
||||
* @return 迷宫节点数组地址
|
||||
*/
|
||||
maze_node_p read_maze_file(char* filename);
|
||||
|
||||
/**
|
||||
* 打印整个迷宫
|
||||
* @param node_array 迷宫数组
|
||||
*/
|
||||
void print_maze(maze_node_p node_array);
|
||||
|
||||
/**
|
||||
* 释放迷宫节点数组占据的空间
|
||||
* @param node_array 迷宫节点数组引用
|
||||
*/
|
||||
void maze_node_free(maze_node_p& node_array);
|
||||
|
||||
#endif //MAZE_MAZE_NODE_H
|
83
maze/include/stack.h
Normal file
83
maze/include/stack.h
Normal file
@@ -0,0 +1,83 @@
|
||||
//
|
||||
// Created by ricardo on 2022/10/25.
|
||||
//
|
||||
|
||||
#ifndef MAZE_STACK_H
|
||||
#define MAZE_STACK_H
|
||||
|
||||
#include "cstdlib"
|
||||
#include "maze_node.h"
|
||||
|
||||
// 默认的栈大小
|
||||
#define DEFAULT_STACK_LENGTH 200
|
||||
|
||||
// 由于将迷宫中的所有节点都储存在数组中
|
||||
// 存储路径的栈就不用存储节点的指针
|
||||
// 而是直接存储节点在数组中的索引
|
||||
struct stack {
|
||||
int* top;
|
||||
int* base;
|
||||
int stack_size;
|
||||
};
|
||||
|
||||
typedef struct stack stack_t;
|
||||
typedef struct stack* stack_p;
|
||||
|
||||
/**
|
||||
* 初始化栈空间
|
||||
* @param s 栈结构体的引用
|
||||
* @return 栈是否创建成功
|
||||
*/
|
||||
bool init_stack(stack_t& s);
|
||||
|
||||
/**
|
||||
* 判断栈是否为空
|
||||
* @param s 对于栈结构体的引用
|
||||
* @return
|
||||
*/
|
||||
bool stack_is_empty(const stack_t& s);
|
||||
|
||||
/**
|
||||
* 判断栈是否已满
|
||||
* @param s 对于结构体的引用
|
||||
* @return
|
||||
*/
|
||||
bool stack_is_full(const stack_t& s);
|
||||
|
||||
/**
|
||||
* 在栈中压入元素
|
||||
* @param s 栈引用
|
||||
* @param value 被压入栈的值
|
||||
* @return 压入栈是否成功
|
||||
*/
|
||||
bool stack_push(stack_t& s, int index);
|
||||
|
||||
/**
|
||||
* 在栈中弹出元素
|
||||
* @param s 栈引用
|
||||
* @param value 被弹出栈的值
|
||||
* @return 弹出栈是否成功
|
||||
*/
|
||||
bool stack_pop(stack_t& s, int* index);
|
||||
|
||||
/**
|
||||
* 获得栈底的元素
|
||||
* @param s 栈引用
|
||||
* @return
|
||||
*/
|
||||
int stack_get_bottom(const stack_t& s);
|
||||
|
||||
/**
|
||||
* 获得栈顶的元素
|
||||
* @param s 栈引用
|
||||
* @return
|
||||
*/
|
||||
int stack_get_top(const stack_t& s);
|
||||
|
||||
/**
|
||||
* 释放栈所占用的空间
|
||||
* @param s 栈引用
|
||||
*/
|
||||
void stack_free(stack_t& s);
|
||||
|
||||
#endif //MAZE_STACK_H
|
76
maze/main.cpp
Normal file
76
maze/main.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#include "maze_node.h"
|
||||
#include "stack.h"
|
||||
#include "cstdio"
|
||||
|
||||
int main()
|
||||
{
|
||||
char config_file[10] = "maze.txt";
|
||||
maze_node_p node_array = read_maze_file(config_file);
|
||||
print_maze(node_array);
|
||||
|
||||
// 输入迷宫的开始和结束节点
|
||||
int begin_node, end_node;
|
||||
printf("Please enter the start node:\n");
|
||||
scanf("%d", &begin_node);
|
||||
printf("Please enter the end node:\n");
|
||||
scanf("%d", &end_node);
|
||||
|
||||
// 初始化储存路径的栈
|
||||
stack_t path_stack;
|
||||
// 显然栈的最大大小就是迷宫中节点的数量
|
||||
// 但是由于栈判满的原因需要多一个位置
|
||||
path_stack.stack_size = node_number + 1;
|
||||
init_stack(path_stack);
|
||||
|
||||
// 初始化将起点填入栈中
|
||||
stack_push(path_stack, begin_node - 1);
|
||||
|
||||
while (stack_get_top(path_stack) + 1 != end_node)
|
||||
{
|
||||
maze_connect_node_p& node = node_array[stack_get_top(path_stack)].now_node;
|
||||
if (node == nullptr)
|
||||
{
|
||||
// 节点已经遍历完不抱希望了
|
||||
// 这个值仅占位
|
||||
int temp;
|
||||
stack_pop(path_stack, &temp);
|
||||
continue;
|
||||
}
|
||||
// 遍历栈确定目标节点不在栈中
|
||||
bool flag = false;
|
||||
int* p = path_stack.base;
|
||||
while (p != path_stack.top)
|
||||
{
|
||||
if (node->index == *p)
|
||||
{
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
if (!flag)
|
||||
{
|
||||
// 如果在栈中没发现这个节点
|
||||
stack_push(path_stack, node->index);
|
||||
}
|
||||
// 将未探索的节点置为下一个
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
// 打印路径栈
|
||||
int* p = path_stack.base;
|
||||
printf("%d", *p + 1);
|
||||
p++;
|
||||
while (p != path_stack.top)
|
||||
{
|
||||
printf("->%d", *p + 1);
|
||||
p++;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
stack_free(path_stack);
|
||||
maze_node_free(node_array);
|
||||
|
||||
return 0;
|
||||
}
|
20
maze/maze.txt
Normal file
20
maze/maze.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
17
|
||||
1-3
|
||||
2-3
|
||||
3-5
|
||||
3-4
|
||||
3-7
|
||||
3-8
|
||||
4-6
|
||||
7-8
|
||||
7-11
|
||||
8-9
|
||||
8-12
|
||||
9-13
|
||||
11-12
|
||||
12-13
|
||||
13-14
|
||||
14-10
|
||||
13-16
|
||||
16-15
|
||||
16-17
|
110
maze/src/maze_node.cpp
Normal file
110
maze/src/maze_node.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
#include "maze_node.h"
|
||||
#include "cstdlib"
|
||||
#include "cstdio"
|
||||
|
||||
int node_number;
|
||||
|
||||
maze_node_p create_maze_node_array(int num)
|
||||
{
|
||||
auto node = (maze_node_p) malloc(num * sizeof(maze_node_t));
|
||||
maze_node_p p = node;
|
||||
for (int i = 1; i <= num; ++i) {
|
||||
p->id = i;
|
||||
p->connect_maze_nodes = nullptr;
|
||||
p++;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
bool maze_node_add_connect_node(maze_node_t& node, int target)
|
||||
{
|
||||
auto new_node = (maze_connect_node_p) malloc(sizeof(maze_connect_node_t));
|
||||
if (new_node == nullptr)
|
||||
{
|
||||
// 分配空间失败
|
||||
return false;
|
||||
}
|
||||
|
||||
new_node->next = nullptr;
|
||||
new_node->index = target;
|
||||
|
||||
if (node.connect_maze_nodes == nullptr)
|
||||
{
|
||||
node.connect_maze_nodes = new_node;
|
||||
// 遍历链表总是从头开始
|
||||
node.now_node = new_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
maze_connect_node_p connect_node = node.connect_maze_nodes;
|
||||
|
||||
while (connect_node->next != nullptr)
|
||||
{
|
||||
// 找到链表末节点
|
||||
connect_node = connect_node->next;
|
||||
}
|
||||
|
||||
connect_node->next = new_node;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
maze_node_p read_maze_file(char* filename)
|
||||
{
|
||||
FILE* config_file;
|
||||
char buffer[10];
|
||||
|
||||
config_file = fopen(filename, "r");
|
||||
|
||||
// 配置文件的第一行要求是迷宫中节点的总数
|
||||
fgets(buffer, sizeof buffer, config_file);
|
||||
char* point;
|
||||
node_number = (int )strtol(buffer, &point, 10);
|
||||
|
||||
maze_node_p node_array = create_maze_node_array(node_number);
|
||||
|
||||
while (fgets(buffer, sizeof buffer, config_file) != nullptr)
|
||||
{
|
||||
int node1, node2;
|
||||
sscanf(buffer, "%d-%d", &node1, &node2);
|
||||
|
||||
// 数组中的索引总是比编号小1
|
||||
maze_node_add_connect_node(node_array[node1 - 1], node2 - 1);
|
||||
maze_node_add_connect_node(node_array[node2 - 1], node1 - 1);
|
||||
}
|
||||
|
||||
fclose(config_file);
|
||||
|
||||
return node_array;
|
||||
}
|
||||
|
||||
void print_maze(maze_node_p node_array)
|
||||
{
|
||||
for (int i = 0; i < node_number; ++i) {
|
||||
maze_node_t node = node_array[i];
|
||||
maze_connect_node_p p = node.connect_maze_nodes;
|
||||
while (p != nullptr)
|
||||
{
|
||||
printf("%d->%d\n", node.id, node_array[p->index].id);
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void maze_node_free(maze_node_p& node_array)
|
||||
{
|
||||
for(int i = 0; i < node_number; i++)
|
||||
{
|
||||
maze_connect_node_p node = node_array[i].connect_maze_nodes;
|
||||
while (node != nullptr)
|
||||
{
|
||||
maze_connect_node_p temp = node;
|
||||
node = node->next;
|
||||
free(temp);
|
||||
}
|
||||
}
|
||||
|
||||
free(node_array);
|
||||
node_array = nullptr;
|
||||
}
|
81
maze/src/stack.cpp
Normal file
81
maze/src/stack.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
//
|
||||
// Created by ricardo on 2022/10/25.
|
||||
//
|
||||
#include "stack.h"
|
||||
|
||||
bool init_stack(stack_t& s)
|
||||
{
|
||||
if (s.stack_size == 0)
|
||||
{
|
||||
// 如果没有设置栈的大小
|
||||
// 就设置为默认大小
|
||||
s.stack_size = DEFAULT_STACK_LENGTH;
|
||||
}
|
||||
|
||||
auto p = (int* ) malloc(sizeof(int));
|
||||
if (p == nullptr)
|
||||
{
|
||||
// 空间分配失败
|
||||
return false;
|
||||
}
|
||||
|
||||
s.base = p;
|
||||
s.top = p;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool stack_is_empty(const stack& s)
|
||||
{
|
||||
return s.base == s.top;
|
||||
}
|
||||
|
||||
bool stack_is_full(const stack& s)
|
||||
{
|
||||
return s.base + s.stack_size == s.top;
|
||||
}
|
||||
|
||||
bool stack_push(stack& s,int index)
|
||||
{
|
||||
if (stack_is_full(s))
|
||||
{
|
||||
// 栈已满
|
||||
return false;
|
||||
}
|
||||
|
||||
*s.top = index;
|
||||
s.top++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool stack_pop(stack& s, int* index)
|
||||
{
|
||||
if (stack_is_empty(s))
|
||||
{
|
||||
// 栈为空
|
||||
return false;
|
||||
}
|
||||
|
||||
*index = *s.top;
|
||||
s.top--;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int stack_get_bottom(const stack_t& s)
|
||||
{
|
||||
return *s.base;
|
||||
}
|
||||
|
||||
int stack_get_top(const stack_t& s)
|
||||
{
|
||||
return *(s.top-1);
|
||||
}
|
||||
|
||||
void stack_free(stack_t& s)
|
||||
{
|
||||
free(s.base);
|
||||
s.base = nullptr;
|
||||
s.top = nullptr;
|
||||
s.stack_size = 0;
|
||||
}
|
Reference in New Issue
Block a user