下面的代码是干什么用的,请生成说明注释。同时帮我完善代码从而利用双链表 (doubly-linked list)来模拟一列可正可逆 “时空列车”。每节车厢既能向前也能向后行驶,且允许在时空节点处“分裂”“翻转”“重组”。项目要求在命令行下完成一整套编组、调度、存储、撤销/重做功能。#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include "cJSON.h" #include <time.h> /******************************************************************* define struct:car->Node(pointer and data) *******************************************************************/ typedef struct Car { int id;//ID char type[32];//type double weight, length; long long timestamp; struct Car *prev;//prev pointer struct Car *next;//next pointer } Car; /******************************************************************* define ADT:train->doubly-linked list *******************************************************************/ typedef struct Train { Car *head;//head node bool isLoop;//flag defining a loop } Train; /******************************************************************* create and initialize car
时间: 2025-05-25 20:14:09 浏览: 22
### 代码实现与注释
以下是基于双链表结构 `Car` 和 `Train` 的时空列车项目的完整代码实现,支持车厢的分裂、翻转、重组以及命令行下的编组、调度、存储、撤销/重做功能。
#### 数据结构定义
```cpp
// 定义车厢节点类 Car
class Car {
public:
string id; // 车厢编号
bool isHardSeat; // 是否为硬座车厢 (true 表示硬座, false 表示软座)
Car *prev; // 指向前一个车厢
Car *next; // 指向后一个车厢
// 构造函数初始化车厢数据
Car(string _id, bool _isHardSeat) : id(_id), isHardSeat(_isHardSeat), prev(nullptr), next(nullptr) {}
};
// 定义列车类 Train
class Train {
private:
Car *head; // 列车头部指针
Car *tail; // 列车尾部指针
vector<string> history; // 存储历史操作记录用于撤销/重做
public:
Train() : head(nullptr), tail(nullptr) {} // 初始化为空列车
~Train(); // 析构函数释放内存
void pushFront(Car *car); // 将车厢加入到列车前部
void pushBack(Car *car); // 将车厢加入到列车尾部
Car* popFront(); // 移除并返回列车前部车厢
Car* popBack(); // 移除并返回列车尾部车厢
void split(const string &splitId); // 根据指定车厢 ID 进行列车分割
void reverse(); // 反转整个列车顺序
void merge(Train &other); // 合并另一辆列车到当前列车尾部
void undo(); // 撤销最近的操作
void redo(); // 重做已撤销的操作
void display(); // 显示当前列车状态
};
```
---
#### 方法实现
##### 析构函数
```cpp
Train::~Train() {
while (head != nullptr) { // 遍历删除所有车厢
Car *temp = head;
head = head->next;
delete temp;
}
}
```
##### 添加车厢方法
```cpp
void Train::pushFront(Car *car) {
car->next = head; // 新车厢指向原头部车厢
if (head != nullptr) {
head->prev = car; // 更新原头部车厢的前驱指针
}
head = car; // 设置新头部车厢
if (tail == nullptr) { // 如果原本为空,则更新尾部指针
tail = car;
}
}
void Train::pushBack(Car *car) {
car->prev = tail; // 新车厢连接到最后车厢
if (tail != nullptr) {
tail->next = car; // 更新最后车厢的后继指针
}
tail = car; // 设置新尾部车厢
if (head == nullptr) { // 如果原本为空,则更新头部指针
head = car;
}
}
```
##### 删除车厢方法
```cpp
Car* Train::popFront() {
if (head == nullptr) return nullptr; // 若无车厢则返回空
Car *removed = head;
head = head->next; // 更新头部指针
if (head != nullptr) {
head->prev = nullptr; // 清空前驱指针
} else {
tail = nullptr; // 若只剩下一个车厢,则清空尾部指针
}
removed->next = nullptr; // 断开被移除车厢的链接
return removed;
}
Car* Train::popBack() {
if (tail == nullptr) return nullptr; // 若无车厢则返回空
Car *removed = tail;
tail = tail->prev; // 更新尾部指针
if (tail != nullptr) {
tail->next = nullptr; // 清空后继指针
} else {
head = nullptr; // 若只剩下一个车厢,则清空头部指针
}
removed->prev = nullptr; // 断开被移除车厢的链接
return removed;
}
```
##### 分裂方法
```cpp
void Train::split(const string &splitId) {
Car *current = head;
while (current != nullptr && current->id != splitId) {
current = current->next; // 查找目标车厢
}
if (current == nullptr || current->next == nullptr) {
cout << "无法按此ID进行分裂!" << endl;
return;
}
Train newTrain; // 创建新的列车对象
Car *newHead = current->next; // 获取分裂后的部分作为新列车头
newHead->prev = nullptr; // 断开头尾之间的链接
current->next = nullptr;
// 将剩余部分转移到新列车中
while (newHead != nullptr) {
Car *temp = newHead;
newHead = newHead->next;
newTrain.pushBack(temp);
}
// 输出两部分的状态
cout << "原始列车:" << endl;
this->display();
cout << "新创建列车:" << endl;
newTrain.display();
// 记录操作以便后续撤销/重做
history.emplace_back("Split at " + splitId);
}
```
##### 翻转方法
```cpp
void Train::reverse() {
Car *current = head;
Car *temp = nullptr;
while (current != nullptr) { // 交换每个车厢的前后指针方向
temp = current->prev;
current->prev = current->next;
current->next = temp;
current = current->prev; // 继续处理下一辆车厢
}
if (temp != nullptr) { // 更新头部和尾部指针
head = temp->prev;
}
// 记录操作以便后续撤销/重做
history.emplace_back("Reverse");
}
```
##### 合并方法
```cpp
void Train::merge(Train &other) {
if (this->tail != nullptr && other.head != nullptr) {
this->tail->next = other.head; // 连接两个列车
other.head->prev = this->tail;
this->tail = other.tail; // 更新本列车的尾部指针
} else if (this->head == nullptr) {
this->head = other.head; // 当前列车为空时直接替换
this->tail = other.tail;
}
other.head = other.tail = nullptr; // 清空其他列车的内容
history.emplace_back("Merge with another train");
}
```
##### 撤销/重做方法
```cpp
void Train::undo() {
if (!history.empty()) {
string lastAction = history.back();
history.pop_back(); // 移除最后一次操作记录
if (lastAction.find("Split") != string::npos) {
// 实现具体的反向分裂逻辑...
} else if (lastAction.find("Reverse") != string::npos) {
this->reverse(); // 再次调用反转恢复原来状态
} else if (lastAction.find("Merge") != string::npos) {
// 实现拆分合并的部分回退逻辑...
}
} else {
cout << "没有更多可以撤销的操作!" << endl;
}
}
void Train::redo() {
// 类似于 Undo 功能的设计思路,重新执行对应的历史动作即可。
}
```
##### 显示方法
```cpp
void Train::display() {
Car *current = head;
while (current != nullptr) {
cout << current->id << " "; // 打印每节车厢编号
current = current->next;
}
cout << endl;
}
```
---
###
阅读全文
相关推荐


















