add: data-structure-lab & compiler-lab
This commit is contained in:
1
josephus/.gitignore
vendored
Normal file
1
josephus/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.idea/
|
12
josephus/CMakeLists.txt
Normal file
12
josephus/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||
|
||||
project(josephus)
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR}/include)
|
||||
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC)
|
||||
|
||||
add_executable(josephus main.cpp ${SRC})
|
82
josephus/include/LinkedList.h
Normal file
82
josephus/include/LinkedList.h
Normal file
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// Created by ricardo on 9/26/22.
|
||||
//
|
||||
|
||||
#ifndef JOSEPHUS_LINKED_LIST_H
|
||||
#define JOSEPHUS_LINKED_LIST_H
|
||||
#include "cstdlib"
|
||||
#include "cstring"
|
||||
#include "cstdio"
|
||||
|
||||
#include "define.h"
|
||||
|
||||
/**
|
||||
* 列表节点结构体
|
||||
*/
|
||||
struct node {
|
||||
int ID;
|
||||
char Name[MAX_NAME_LENGTH];
|
||||
int Age;
|
||||
int Gender;
|
||||
struct node* next;
|
||||
};
|
||||
|
||||
typedef struct node node_t;
|
||||
typedef struct node* node_p;
|
||||
|
||||
/**
|
||||
* 创建循环列表
|
||||
* @param head 头节点地址的引用
|
||||
* @return true 创建成功
|
||||
* @return false 创建失败
|
||||
*/
|
||||
bool init_linked_list(node_p& head);
|
||||
|
||||
/**
|
||||
* 销毁链表
|
||||
* @param head 链表头节点的地址
|
||||
*/
|
||||
void destroy_linked_list(node_p& head);
|
||||
|
||||
/**
|
||||
* 创建一个链表中的节点
|
||||
* @param node 新节点地址引用
|
||||
* @param id 人的编号
|
||||
* @param age 人的年龄
|
||||
* @param gender 人的性别
|
||||
* @param name 人的姓名字符串
|
||||
* @return true 创建成功
|
||||
* @return false 创建失败
|
||||
*/
|
||||
bool create_node(node_p& node, int id, int age, int gender, char* name);
|
||||
|
||||
/**
|
||||
* 在链表的末尾插入新节点
|
||||
* 虽然是循环链表 我们不妨认为头节点前的节点
|
||||
* @param head 链表头节点的引用
|
||||
* @param new_node 需要插入的新节点
|
||||
*/
|
||||
void append_node(const node_p& head, node_p new_node);
|
||||
|
||||
/**
|
||||
* 从链表中删除指定的节点
|
||||
* @param head 链表头节点的引用
|
||||
* @param target_node 需要删除的目标节点
|
||||
* @return true 删除成功
|
||||
* @return false 删除失败 一般是目标节点非法
|
||||
*/
|
||||
bool delete_node(const node_p& head, node_p target_node);
|
||||
|
||||
/**
|
||||
* 打印指定节点记录人员的信息
|
||||
* @param node 对指定节点的引用
|
||||
*/
|
||||
void print_node(const node_p& node);
|
||||
|
||||
/**
|
||||
* 打印链表中每个节点的值
|
||||
* @param head 链表头节点的引用
|
||||
*/
|
||||
void print_linked_list(const node_p& head);
|
||||
|
||||
#endif //JOSEPHUS_LINKED_LIST_H
|
16
josephus/include/define.h
Normal file
16
josephus/include/define.h
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// Created by ricardo on 2022/9/26.
|
||||
//
|
||||
|
||||
#ifndef JOSEPHUS_DEFINE_H
|
||||
#define JOSEPHUS_DEFINE_H
|
||||
// 男性
|
||||
#define MALE 0
|
||||
// 女性
|
||||
#define FEMALE 1
|
||||
|
||||
// 姓名字符串的最大长度
|
||||
#define MAX_NAME_LENGTH 20
|
||||
#define MAX_GENDER_LENGTH 10
|
||||
|
||||
#endif //JOSEPHUS_DEFINE_H
|
8
josephus/input.txt
Normal file
8
josephus/input.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
6
|
||||
1 zyl male 1
|
||||
2 zzyl male 2
|
||||
3 zzzyl female 3
|
||||
4 zyyl female 4
|
||||
5 zyyyl female 40
|
||||
6 zyll female 45
|
||||
0 4 1
|
135
josephus/main.cpp
Normal file
135
josephus/main.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
//
|
||||
// Created by ricardo on 9/26/22.
|
||||
//
|
||||
#include "LinkedList.h"
|
||||
#include "define.h"
|
||||
|
||||
node_p read_input()
|
||||
{
|
||||
int age, id, gender;
|
||||
char name[MAX_NAME_LENGTH];
|
||||
char gender_string[MAX_GENDER_LENGTH];
|
||||
|
||||
// 性别字符串
|
||||
const char* male_string = "male";
|
||||
const char* female_string = "female";
|
||||
|
||||
scanf("%d %s %s %d", &id, name, gender_string, &age);
|
||||
|
||||
// 匹配输入的性别字符串
|
||||
if (strcmp(gender_string, male_string) == 0)
|
||||
{
|
||||
gender = MALE;
|
||||
}
|
||||
else if (strcmp(gender_string, female_string) == 0)
|
||||
{
|
||||
gender = FEMALE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果匹配失败说明输入非法
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
node_p node;
|
||||
if (create_node(node, id, age, gender, name))
|
||||
{
|
||||
return node;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// 存储总共的人数
|
||||
int number;
|
||||
// 链表的头节点
|
||||
node_p head;
|
||||
|
||||
if (!init_linked_list(head))
|
||||
{
|
||||
// 创建链表的头节点
|
||||
// 如果创建失败输出错误信息
|
||||
printf("E: Init linked list failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 输入人员列表
|
||||
printf("Hint: Enter number of people join this game:");
|
||||
scanf("%d", &number);
|
||||
printf("Hint: Enter the people information list as id name gender(male|female) age.\n");
|
||||
for (int i = 0; i < number; ++i) {
|
||||
node_p node = read_input();
|
||||
if (node == nullptr)
|
||||
{
|
||||
printf("E: Create Node failed.\n");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
append_node(head, node);
|
||||
}
|
||||
}
|
||||
|
||||
// 打印人员列表
|
||||
print_linked_list(head);
|
||||
|
||||
// 分别记录游戏开始的位置 中间的间隔 最后剩余的人数
|
||||
int begin, middle, left;
|
||||
printf("Hint: Enter the begin(begin from 0), middle and left people number.\n");
|
||||
scanf("%d %d %d", &begin, &middle, &left);
|
||||
|
||||
node_p node = head->next;
|
||||
// 循环到达游戏开始的位置
|
||||
for (int i = 0; i < begin; ++i) {
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
// 这里有点屎
|
||||
// 由于给定的数据是"间隔"
|
||||
// 在遍历时的次数需要+1
|
||||
// 但是当前被选中的节点会被删除 在删除之间需要将指针下移一位
|
||||
// 遍历的次序又需要-1
|
||||
// 故需要在开始前在指针前移一位
|
||||
node = node->next;
|
||||
while (number > left)
|
||||
{
|
||||
// 游戏开始
|
||||
// 由于middle是间隔
|
||||
for (int i = 0; i < middle; ++i) {
|
||||
if (node == head)
|
||||
{
|
||||
// 由于头节点不存储数据
|
||||
// 遍历到头节点需要多遍历一次
|
||||
i--;
|
||||
}
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
if (node == head)
|
||||
{
|
||||
// 如果恰好在末尾遇到head
|
||||
// 无法在循环中处理
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
printf("ID:%d was killed\n", node->ID);
|
||||
node_p target = node;
|
||||
node = node->next;
|
||||
if (!delete_node(head, target))
|
||||
{
|
||||
printf("E: delete node failed.\n");
|
||||
return -1;
|
||||
}
|
||||
number--;
|
||||
}
|
||||
|
||||
print_linked_list(head);
|
||||
|
||||
// 在退出程序之前 释放链表占用的空间
|
||||
destroy_linked_list(head);
|
||||
return 0;
|
||||
}
|
||||
|
132
josephus/src/LinkedList.cpp
Normal file
132
josephus/src/LinkedList.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
//
|
||||
// Created by ricardo on 9/26/22.
|
||||
//
|
||||
#include "LinkedList.h"
|
||||
|
||||
bool init_linked_list(node_p& head)
|
||||
{
|
||||
head = (node_p) malloc(sizeof (node_t));
|
||||
|
||||
if (head == nullptr)
|
||||
{
|
||||
// 空间分配失败
|
||||
return false;
|
||||
}
|
||||
// 由于是创建循环链表 头节点的下一个节点就是头节点
|
||||
head->next = head;
|
||||
return true;
|
||||
}
|
||||
|
||||
void destroy_linked_list(node_p& head)
|
||||
{
|
||||
node_p node = head->next;
|
||||
|
||||
// 先循环处理所有不是头节点的节点
|
||||
while (node != head)
|
||||
{
|
||||
node_p temp = node;
|
||||
node = node->next;
|
||||
free(temp);
|
||||
}
|
||||
|
||||
free(head);
|
||||
head = nullptr;
|
||||
}
|
||||
|
||||
bool create_node(node_p& node, int id, int age, int gender, char* name)
|
||||
{
|
||||
node = (node_p) malloc(sizeof(node_t));
|
||||
|
||||
if (node == nullptr)
|
||||
{
|
||||
// 分配空间失败
|
||||
return false;
|
||||
}
|
||||
|
||||
node->ID = id;
|
||||
node->Age = age;
|
||||
node->Gender = gender;
|
||||
strcpy(node->Name, name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void append_node(const node_p& head, node_p new_node)
|
||||
{
|
||||
node_p node = head->next;
|
||||
|
||||
// 找到头节点前的一个节点
|
||||
while (node->next != head)
|
||||
{
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
node->next = new_node;
|
||||
new_node->next = head;
|
||||
}
|
||||
|
||||
bool delete_node(const node_p& head, node_p target_node)
|
||||
{
|
||||
if (head == target_node)
|
||||
{
|
||||
// 删除头节点时不可行的
|
||||
return false;
|
||||
}
|
||||
|
||||
node_p node = head;
|
||||
|
||||
while (node->next != target_node)
|
||||
{
|
||||
if (node->next == head)
|
||||
{
|
||||
// 循环完了都没找见
|
||||
// 说明查无此节点
|
||||
return false;
|
||||
}
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
node->next = target_node->next;
|
||||
free(target_node);
|
||||
return true;
|
||||
}
|
||||
|
||||
void print_node(const node_p& node)
|
||||
{
|
||||
if (node == nullptr)
|
||||
{
|
||||
// 指定节点为空
|
||||
return;
|
||||
}
|
||||
|
||||
printf("ID:%d|", node->ID);
|
||||
printf("Name:%s|", node->Name);
|
||||
printf("Age:%d|", node->Age);
|
||||
if (node->Gender == MALE)
|
||||
{
|
||||
printf("Gender:Male\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Gender:Female\n");
|
||||
}
|
||||
}
|
||||
|
||||
void print_linked_list(const node_p& head)
|
||||
{
|
||||
if (head == nullptr)
|
||||
{
|
||||
// 头节点为空
|
||||
return;
|
||||
}
|
||||
|
||||
node_p node = head->next;
|
||||
|
||||
while (node != head)
|
||||
{
|
||||
print_node(node);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user