Init Repo
This commit is contained in:
+106
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* common.h - 火车票务管理系统公共头文件
|
||||
* 定义所有模块共享的数据类型、常量、枚举
|
||||
* C++ 版本
|
||||
*/
|
||||
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
using namespace std;
|
||||
|
||||
/* ==================== 系统常量 ==================== */
|
||||
|
||||
constexpr int MAX_TRAINS = 100; // 最大车次数
|
||||
constexpr int MAX_ORDERS = 500; // 最大订单数
|
||||
constexpr int MAX_STATIONS = 50; // 最大站点数
|
||||
constexpr int MAX_QUEUE_SIZE = 100; // 候补队列最大长度
|
||||
constexpr int MAX_STACK_SIZE = 100; // 撤销栈最大深度
|
||||
|
||||
/* ==================== 枚举 ==================== */
|
||||
|
||||
// 订单状态
|
||||
enum class OrderStatus {
|
||||
PAID, // 已支付
|
||||
WAITING, // 候补中
|
||||
REFUNDED // 已退票
|
||||
};
|
||||
|
||||
// 用户角色
|
||||
enum class UserRole {
|
||||
ADMIN, // 管理员
|
||||
PASSENGER // 普通乘客
|
||||
};
|
||||
|
||||
// 操作类型(用于撤销栈)
|
||||
enum class OpType {
|
||||
BUY, // 购票
|
||||
REFUND, // 退票
|
||||
CHANGE // 改签
|
||||
};
|
||||
|
||||
/* ==================== 结构体定义 ==================== */
|
||||
|
||||
// --- 车次信息 ---
|
||||
struct TrainInfo {
|
||||
string trainNo; // 车次号(唯一,如 G1234)
|
||||
string startStation; // 始发站
|
||||
string endStation; // 终点站
|
||||
string departTime; // 出发时间
|
||||
string arriveTime; // 到达时间
|
||||
float price = 0.0f; // 票价
|
||||
int totalSeats = 0; // 总票数
|
||||
int remainSeats = 0; // 余票
|
||||
};
|
||||
|
||||
// --- 订单信息 ---
|
||||
struct OrderInfo {
|
||||
string orderId; // 订单号(唯一,如 O00001)
|
||||
string trainNo; // 关联车次号
|
||||
string passengerName; // 乘客姓名
|
||||
string idCard; // 身份证号
|
||||
int seatNo = 0; // 座位号
|
||||
string orderTime; // 购票时间
|
||||
OrderStatus status = OrderStatus::PAID; // 订单状态
|
||||
};
|
||||
|
||||
// --- 站点/线路信息 ---
|
||||
struct EdgeNode {
|
||||
int toStationId; // 相邻站点编号
|
||||
float weight; // 边权(时长或票价)
|
||||
EdgeNode* next = nullptr;// 下一条边
|
||||
};
|
||||
|
||||
struct VertexNode {
|
||||
int stationId; // 站点编号
|
||||
string stationName; // 站点名称
|
||||
EdgeNode* firstEdge = nullptr; // 邻接表头指针
|
||||
};
|
||||
|
||||
// --- 撤销操作日志 ---
|
||||
struct OperationLog {
|
||||
OpType type; // 操作类型
|
||||
string orderId; // 相关订单号
|
||||
string trainNo; // 相关车次号
|
||||
int seatNo = 0; // 座位号
|
||||
string idCard; // 乘客身份证号
|
||||
string timestamp; // 操作时间
|
||||
};
|
||||
|
||||
// --- 订单状态输出辅助 ---
|
||||
inline const char* OrderStatusStr(OrderStatus s) {
|
||||
switch (s) {
|
||||
case OrderStatus::PAID: return "已支付";
|
||||
case OrderStatus::WAITING: return "候补中";
|
||||
case OrderStatus::REFUNDED:return "已退票";
|
||||
default: return "未知";
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* COMMON_H */
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* graph.cpp - 线路网络图模块实现(邻接表存储)
|
||||
* 负责人:组员C
|
||||
*
|
||||
* TODO: 组员C 请在此文件中实现所有声明的函数
|
||||
* C++ 版本
|
||||
*/
|
||||
|
||||
#include "graph.h"
|
||||
#include <queue> // BFS 可用 STL queue 辅助,或自己用数组模拟
|
||||
#include <climits> // INT_MAX
|
||||
|
||||
/* ==================== 全局变量 ==================== */
|
||||
|
||||
StationGraph stationGraph;
|
||||
|
||||
/* ==================== 图基础操作 ==================== */
|
||||
|
||||
void InitGraph(StationGraph& G) {
|
||||
// TODO: vertexCount = 0, edgeCount = 0
|
||||
// 遍历 vertices[],firstEdge = nullptr
|
||||
}
|
||||
|
||||
int AddVertex(StationGraph& G, int stationId, const string& stationName) {
|
||||
// TODO: 检查是否已存在、是否超过 MAX_STATIONS
|
||||
// 创建新顶点,vertexCount++
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool AddEdge(StationGraph& G, int fromId, int toId, float weight) {
|
||||
// TODO: 无向图,需同时添加两条边
|
||||
// 1. 创建 EdgeNode{toId, weight} 插入 from 的邻接表头
|
||||
// 2. 创建 EdgeNode{fromId, weight} 插入 to 的邻接表头
|
||||
// edgeCount++
|
||||
return false;
|
||||
}
|
||||
|
||||
int FindVertex(const StationGraph& G, int stationId) {
|
||||
// TODO: 遍历 vertices[],按 stationId 查找下标
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ==================== 图遍历算法 ==================== */
|
||||
|
||||
void DFS(const StationGraph& G, int startIdx, bool visited[]) {
|
||||
// TODO: 递归深度优先遍历
|
||||
// 1. 标记 visited[startIdx] = true,输出站点名
|
||||
// 2. 遍历该顶点的邻接表,对每个未访问的邻接点递归 DFS
|
||||
}
|
||||
|
||||
void BFS(const StationGraph& G, int startIdx) {
|
||||
// TODO: 广度优先遍历,输出最少换乘次数的路径
|
||||
// 用 queue<int> 辅助
|
||||
}
|
||||
|
||||
/* ==================== 最短路径算法 ==================== */
|
||||
|
||||
void Dijkstra(const StationGraph& G, int srcIdx,
|
||||
float dist[], int path[]) {
|
||||
// TODO: Dijkstra 最短路径算法
|
||||
// 1. 初始化 dist[] = INF, visited[] = false
|
||||
// 2. dist[src] = 0, path[src] = -1
|
||||
// 3. 循环 vertexCount 次:
|
||||
// a. 选未访问中 dist 最小的顶点 u
|
||||
// b. 标记 visited[u] = true
|
||||
// c. 遍历 u 的邻接表,松弛操作
|
||||
}
|
||||
|
||||
void PrintPath(const StationGraph& G, int path[], int destIdx) {
|
||||
// TODO: 递归回溯打印路径
|
||||
// if (path[destIdx] != -1) PrintPath(G, path, path[destIdx])
|
||||
// cout << G.vertices[destIdx].stationName
|
||||
}
|
||||
|
||||
void RecommendTransfer(const StationGraph& G,
|
||||
const string& startName, const string& endName) {
|
||||
// TODO:
|
||||
// 1. 按站名查找顶点下标
|
||||
// 2. 调用 Dijkstra
|
||||
// 3. 调用 PrintPath 输出换乘方案
|
||||
}
|
||||
|
||||
/* ==================== 最小生成树(可选加分) ==================== */
|
||||
|
||||
void PrimMST(const StationGraph& G) {
|
||||
// TODO: Prim 算法实现最小生成树
|
||||
}
|
||||
|
||||
/* ==================== 文件读写 ==================== */
|
||||
|
||||
int loadStationsFromFile(const string& filename) {
|
||||
// TODO: 用 ifstream 读取 CSV
|
||||
// 解析站点顶点和邻接边,调用 AddVertex / AddEdge 构建图
|
||||
// 边的格式: "相邻站点(车次号:边权)",多条边用 ; 分隔
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ==================== 乘客接口 ==================== */
|
||||
|
||||
void passengerFindTransfer() {
|
||||
// TODO:
|
||||
// 1. 输入起点站名和终点站名
|
||||
// 2. 调用 RecommendTransfer
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* graph.h - 线路网络图模块(邻接表存储)
|
||||
* 负责人:组员C
|
||||
*
|
||||
* 核心数据结构:图 StationGraph(邻接表)
|
||||
* 算法:DFS 深度优先遍历、BFS 广度优先遍历、Dijkstra 最短路径
|
||||
* C++ 版本
|
||||
*/
|
||||
|
||||
#ifndef GRAPH_H
|
||||
#define GRAPH_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/* ==================== 图结构 ==================== */
|
||||
|
||||
struct StationGraph {
|
||||
VertexNode vertices[MAX_STATIONS]; // 顶点数组
|
||||
int vertexCount = 0; // 当前顶点数
|
||||
int edgeCount = 0; // 边数
|
||||
};
|
||||
|
||||
/* ==================== 图基础操作 ==================== */
|
||||
|
||||
void InitGraph(StationGraph& G);
|
||||
int AddVertex(StationGraph& G, int stationId, const string& stationName);
|
||||
bool AddEdge(StationGraph& G, int fromId, int toId, float weight);
|
||||
int FindVertex(const StationGraph& G, int stationId);
|
||||
|
||||
/* ==================== 图遍历算法 ==================== */
|
||||
|
||||
// 深度优先遍历(DFS)—— 递归实现
|
||||
void DFS(const StationGraph& G, int startIdx, bool visited[]);
|
||||
|
||||
// 广度优先遍历(BFS)—— 队列实现,找最少换乘次数路径
|
||||
void BFS(const StationGraph& G, int startIdx);
|
||||
|
||||
/* ==================== 最短路径算法 ==================== */
|
||||
|
||||
// Dijkstra 最短路径 —— 最优换乘推荐
|
||||
// dist[]: 从 src 到各站点的最短距离
|
||||
// path[]: 前驱节点数组,用于回溯路径
|
||||
void Dijkstra(const StationGraph& G, int srcIdx,
|
||||
float dist[], int path[]);
|
||||
|
||||
// 打印路径(回溯 path[] 数组)
|
||||
void PrintPath(const StationGraph& G, int path[], int destIdx);
|
||||
|
||||
// 推荐换乘方案(用户接口:输入起点/终点站名,输出最优方案)
|
||||
void RecommendTransfer(const StationGraph& G,
|
||||
const string& startName, const string& endName);
|
||||
|
||||
/* ==================== 最小生成树(可选加分) ==================== */
|
||||
|
||||
// Prim 算法 —— 最小总里程连通所有站点
|
||||
void PrimMST(const StationGraph& G);
|
||||
|
||||
/* ==================== 文件读写 ==================== */
|
||||
|
||||
int loadStationsFromFile(const string& filename);
|
||||
|
||||
/* ==================== 乘客接口 ==================== */
|
||||
|
||||
void passengerFindTransfer();
|
||||
|
||||
#endif /* GRAPH_H */
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* hash.cpp - 订单哈希查找与销售统计模块实现
|
||||
* 负责人:组员C
|
||||
*
|
||||
* TODO: 组员C 请在此文件中实现所有声明的函数
|
||||
* C++ 版本
|
||||
*/
|
||||
|
||||
#include "hash.h"
|
||||
#include "train.h" // 需要 trainList 做统计关联
|
||||
|
||||
/* ==================== 全局变量 ==================== */
|
||||
|
||||
HashNode* orderHashTable[HASH_SIZE] = {nullptr};
|
||||
|
||||
/* ==================== 哈希表操作 ==================== */
|
||||
|
||||
int Hash(const string& idCard) {
|
||||
// TODO: 哈希函数
|
||||
// 方案1:取身份证后6位 % HASH_SIZE
|
||||
// 方案2:逐字符累加 ASCII 值 % HASH_SIZE
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool HashInsert(HashNode* hashTable[], const OrderInfo& order) {
|
||||
// TODO: 链地址法插入
|
||||
// 1. 计算 hash = Hash(order.idCard)
|
||||
// 2. 创建新 HashNode,头插法插入 hashTable[hash]
|
||||
return false;
|
||||
}
|
||||
|
||||
const HashNode* HashSearch(HashNode* const hashTable[], const string& idCard) {
|
||||
// TODO: 哈希查找
|
||||
// 1. 计算 hash = Hash(idCard)
|
||||
// 2. 遍历 hashTable[hash] 链表,匹配 idCard
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const OrderInfo* HashSearchByOrderId(HashNode* const hashTable[],
|
||||
const string& orderId) {
|
||||
// TODO: 按订单号查找(需遍历所有桶)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool HashDelete(HashNode* hashTable[], const string& orderId) {
|
||||
// TODO: 哈希删除
|
||||
// 遍历链表找到目标节点,从链表中移除并 delete
|
||||
return false;
|
||||
}
|
||||
|
||||
void InitHashTable(HashNode* hashTable[]) {
|
||||
// TODO: 所有桶置为 nullptr
|
||||
}
|
||||
|
||||
void DestroyHashTable(HashNode* hashTable[]) {
|
||||
// TODO: 遍历每个桶,释放链表所有节点
|
||||
}
|
||||
|
||||
/* ==================== 统计功能 ==================== */
|
||||
|
||||
int CountSalesByTrain(const string& trainNo) {
|
||||
// TODO: 统计某车次已支付订单数
|
||||
// 遍历所有桶的链表,匹配 trainNo 且 status == PAID
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CountTrafficByRoute(const string& startStation, const string& endStation) {
|
||||
// TODO: 统计某线路客流量
|
||||
// 需要关联车次表(trainList)判断始发-终点站
|
||||
return 0;
|
||||
}
|
||||
|
||||
float CountRevenueByPeriod(const string& startTime, const string& endTime) {
|
||||
// TODO: 统计某时间段总收入
|
||||
// 匹配 orderTime 在区间内的已支付订单,累加对应车次的票价
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void HotTrainRanking(TrainInfo ranking[], int topN) {
|
||||
// TODO: 热门车次排行
|
||||
// 统计每个车次销售量 → 排序 → 取前 topN
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* hash.h - 订单哈希查找与销售统计模块
|
||||
* 负责人:组员C
|
||||
*
|
||||
* 核心数据结构:哈希表(链地址法解决冲突)
|
||||
* 功能:按身份证号快速查找订单、销售统计
|
||||
* C++ 版本
|
||||
*/
|
||||
|
||||
#ifndef HASH_H
|
||||
#define HASH_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/* ==================== 哈希表结构 ==================== */
|
||||
|
||||
constexpr int HASH_SIZE = 101; // 哈希表大小(素数,减少冲突)
|
||||
|
||||
// 哈希表节点(链表)
|
||||
struct HashNode {
|
||||
OrderInfo order; // 订单数据
|
||||
HashNode* next = nullptr; // 链表下一节点
|
||||
};
|
||||
|
||||
/* ==================== 哈希表操作 ==================== */
|
||||
|
||||
// 哈希函数(字符累加法 + 除留余数)
|
||||
int Hash(const string& idCard);
|
||||
|
||||
// 插入订单到哈希表
|
||||
bool HashInsert(HashNode* hashTable[], const OrderInfo& order);
|
||||
|
||||
// 按身份证号查找订单
|
||||
const HashNode* HashSearch(HashNode* const hashTable[], const string& idCard);
|
||||
|
||||
// 按订单号查找(顺序扫描哈希表)
|
||||
const OrderInfo* HashSearchByOrderId(HashNode* const hashTable[],
|
||||
const string& orderId);
|
||||
|
||||
// 删除哈希表中的订单
|
||||
bool HashDelete(HashNode* hashTable[], const string& orderId);
|
||||
|
||||
// 初始化 / 销毁哈希表
|
||||
void InitHashTable(HashNode* hashTable[]);
|
||||
void DestroyHashTable(HashNode* hashTable[]);
|
||||
|
||||
/* ==================== 统计功能 ==================== */
|
||||
|
||||
int CountSalesByTrain(const string& trainNo);
|
||||
int CountTrafficByRoute(const string& startStation, const string& endStation);
|
||||
float CountRevenueByPeriod(const string& startTime, const string& endTime);
|
||||
void HotTrainRanking(TrainInfo ranking[], int topN);
|
||||
|
||||
#endif /* HASH_H */
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
* main.cpp - 火车票务管理系统主程序
|
||||
* 负责菜单调度、登录验证、模块整合
|
||||
* C++ 版本
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "train.h"
|
||||
#include "order.h"
|
||||
#include "graph.h"
|
||||
#include "hash.h"
|
||||
#include "stack.h"
|
||||
|
||||
/* ==================== 全局数据 ==================== */
|
||||
|
||||
TrainList trainList; // 车次顺序表
|
||||
OrderInfo orderArray[MAX_ORDERS]; // 订单数组
|
||||
int orderCount = 0; // 订单总数
|
||||
StationGraph stationGraph; // 站点图
|
||||
WaitQueue* waitQueues[MAX_TRAINS] = {nullptr}; // 候补队列指针数组
|
||||
OpStack undoStack; // 撤销栈
|
||||
|
||||
/* ==================== 文件路径 ==================== */
|
||||
|
||||
const string TRAINS_CSV = "../data/trains.csv";
|
||||
const string ORDERS_CSV = "../data/orders.csv";
|
||||
const string STATIONS_CSV = "../data/stations.csv";
|
||||
|
||||
/* ==================== 菜单函数声明 ==================== */
|
||||
|
||||
void showMainMenu();
|
||||
void showAdminMenu();
|
||||
void showPassengerMenu();
|
||||
|
||||
/* ==================== 主函数 ==================== */
|
||||
|
||||
int main() {
|
||||
cout << "========================================" << endl;
|
||||
cout << " 火车票务管理系统 v1.0 (C++)" << endl;
|
||||
cout << "========================================" << endl << endl;
|
||||
|
||||
// 加载数据
|
||||
cout << "正在加载数据..." << endl;
|
||||
loadTrainsFromFile(TRAINS_CSV);
|
||||
loadOrdersFromFile(ORDERS_CSV);
|
||||
loadStationsFromFile(STATIONS_CSV);
|
||||
cout << "数据加载完成!" << endl << endl;
|
||||
|
||||
// 登录选择
|
||||
int role;
|
||||
while (true) {
|
||||
cout << "请选择登录角色:" << endl;
|
||||
cout << " 1. 管理员" << endl;
|
||||
cout << " 2. 普通乘客" << endl;
|
||||
cout << " 0. 退出系统" << endl;
|
||||
cout << "请输入选项:";
|
||||
cin >> role;
|
||||
cin.ignore(); // 吃掉换行符
|
||||
|
||||
if (role == 0) {
|
||||
cout << endl << "正在保存数据..." << endl;
|
||||
saveTrainsToFile(TRAINS_CSV);
|
||||
saveOrdersToFile(ORDERS_CSV);
|
||||
cout << "数据已保存,感谢使用!" << endl;
|
||||
break;
|
||||
} else if (role == 1) {
|
||||
showAdminMenu();
|
||||
} else if (role == 2) {
|
||||
showPassengerMenu();
|
||||
} else {
|
||||
cout << "输入无效,请重新选择!" << endl << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ==================== 管理员菜单 ==================== */
|
||||
|
||||
void showAdminMenu() {
|
||||
int choice;
|
||||
|
||||
while (true) {
|
||||
cout << endl;
|
||||
cout << "========== 管理员菜单 ==========" << endl;
|
||||
cout << " 1. 新增车次" << endl;
|
||||
cout << " 2. 删除/停运车次" << endl;
|
||||
cout << " 3. 修改车次信息" << endl;
|
||||
cout << " 4. 查看车次列表" << endl;
|
||||
cout << " 5. 查询车次(按车次号)" << endl;
|
||||
cout << " 6. 排序车次(按票价/余票/时间)" << endl;
|
||||
cout << " 7. 查看销售统计" << endl;
|
||||
cout << " 0. 返回上级菜单" << endl;
|
||||
cout << "请输入选项:";
|
||||
cin >> choice;
|
||||
cin.ignore();
|
||||
|
||||
switch (choice) {
|
||||
case 0: return;
|
||||
case 1: adminAddTrain(); break;
|
||||
case 2: adminDeleteTrain(); break;
|
||||
case 3: adminModifyTrain(); break;
|
||||
case 4: adminListTrains(); break;
|
||||
case 5: adminSearchTrain(); break;
|
||||
case 6: adminSortTrains(); break;
|
||||
case 7: adminShowStatistics(); break;
|
||||
default:
|
||||
cout << "输入无效,请重新选择!" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ==================== 乘客菜单 ==================== */
|
||||
|
||||
void showPassengerMenu() {
|
||||
int choice;
|
||||
|
||||
while (true) {
|
||||
cout << endl;
|
||||
cout << "========== 乘客菜单 ==========" << endl;
|
||||
cout << " 1. 查询车次" << endl;
|
||||
cout << " 2. 购票" << endl;
|
||||
cout << " 3. 退票" << endl;
|
||||
cout << " 4. 改签" << endl;
|
||||
cout << " 5. 查看我的订单" << endl;
|
||||
cout << " 6. 查询换乘方案" << endl;
|
||||
cout << " 7. 撤销上一步操作" << endl;
|
||||
cout << " 0. 返回上级菜单" << endl;
|
||||
cout << "请输入选项:";
|
||||
cin >> choice;
|
||||
cin.ignore();
|
||||
|
||||
switch (choice) {
|
||||
case 0: return;
|
||||
case 1: passengerSearchTrain(); break;
|
||||
case 2: passengerBuyTicket(); break;
|
||||
case 3: passengerRefundTicket(); break;
|
||||
case 4: passengerChangeTicket(); break;
|
||||
case 5: passengerViewOrders(); break;
|
||||
case 6: passengerFindTransfer(); break;
|
||||
case 7: passengerUndo(); break;
|
||||
default:
|
||||
cout << "输入无效,请重新选择!" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* order.cpp - 购票/退票/改签模块实现
|
||||
* 负责人:组员B
|
||||
*
|
||||
* TODO: 组员B 请在此文件中实现所有声明的函数
|
||||
* C++ 版本
|
||||
*/
|
||||
|
||||
#include "order.h"
|
||||
#include "train.h" // 需要操作车次余票
|
||||
#include "stack.h" // 需要记录操作日志到撤销栈
|
||||
|
||||
/* ==================== 全局变量 ==================== */
|
||||
|
||||
OrderInfo orderArray[MAX_ORDERS];
|
||||
int orderCount = 0;
|
||||
WaitQueue* waitQueues[MAX_TRAINS] = {nullptr};
|
||||
|
||||
/* ==================== 队列操作 ==================== */
|
||||
|
||||
void InitQueue(WaitQueue& Q) {
|
||||
// TODO: 初始化 front = rear = count = 0
|
||||
}
|
||||
|
||||
bool EnQueue(WaitQueue& Q, const OrderInfo& e) {
|
||||
// TODO: 候补入队(循环队列)
|
||||
// 检查队满 → 返回 false
|
||||
// 将 e 存入 data[rear],rear = (rear+1) % MAX_QUEUE_SIZE,count++
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeQueue(WaitQueue& Q, OrderInfo& e) {
|
||||
// TODO: 候补转正出票(循环队列)
|
||||
// 检查队空 → 返回 false
|
||||
// 取出 data[front],front = (front+1) % MAX_QUEUE_SIZE,count--
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QueueEmpty(const WaitQueue& Q) {
|
||||
// TODO: count == 0
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QueueFull(const WaitQueue& Q) {
|
||||
// TODO: count == MAX_QUEUE_SIZE
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ==================== 订单操作 ==================== */
|
||||
|
||||
string GenerateOrderId() {
|
||||
// TODO: 生成 O00001 格式的自增订单号
|
||||
// 用静态变量记录已生成的序号
|
||||
return "O00000";
|
||||
}
|
||||
|
||||
int BuyTicket(const OrderInfo& order) {
|
||||
// TODO: 购票逻辑
|
||||
// 1. 查出对应车次(trainList 中查找)
|
||||
// 2. 判断 remainSeats > 0:
|
||||
// a. 有余票 → remainSeats--,生成订单,存入 orderArray,
|
||||
// 将操作 Push 到 undoStack
|
||||
// b. 无余票 → 询问是否进入候补队列 → EnQueue
|
||||
return -1;
|
||||
}
|
||||
|
||||
int RefundTicket(const string& orderId) {
|
||||
// TODO: 退票逻辑
|
||||
// 1. 找到订单,status 改为 REFUNDED
|
||||
// 2. 对应车次 remainSeats++
|
||||
// 3. 检查该车次候补队列是否非空:
|
||||
// a. DeQueue → 自动为候补乘客出票,remainSeats--
|
||||
// 4. 将操作 Push 到 undoStack
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ChangeTicket(const string& orderId, const string& newTrainNo) {
|
||||
// TODO: 改签逻辑
|
||||
// 1. 原订单退票(释放原车次余票)
|
||||
// 2. 在新车次购票(扣减新车次余票)
|
||||
// 3. 更新订单的 trainNo 和 seatNo
|
||||
// 4. Push 到 undoStack
|
||||
return -1;
|
||||
}
|
||||
|
||||
int SearchOrdersByIdCard(const string& idCard,
|
||||
OrderInfo results[], int maxResults) {
|
||||
// TODO: 遍历 orderArray,按 idCard 匹配
|
||||
return 0;
|
||||
}
|
||||
|
||||
const OrderInfo* SearchOrderById(const string& orderId) {
|
||||
// TODO: 遍历 orderArray,按 orderId 匹配,返回指针
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* ==================== 文件读写 ==================== */
|
||||
|
||||
int loadOrdersFromFile(const string& filename) {
|
||||
// TODO: 用 ifstream 读取 CSV,填充 orderArray
|
||||
return 0;
|
||||
}
|
||||
|
||||
int saveOrdersToFile(const string& filename) {
|
||||
// TODO: 用 ofstream 写回 CSV
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ==================== 乘客接口 ==================== */
|
||||
|
||||
void passengerBuyTicket() {
|
||||
// TODO: 交互:选择车次 → 输入姓名/身份证 → 生成订单
|
||||
}
|
||||
|
||||
void passengerRefundTicket() {
|
||||
// TODO: 交互:输入订单号 → 执行退票
|
||||
}
|
||||
|
||||
void passengerChangeTicket() {
|
||||
// TODO: 交互:输入订单号 + 新车次号 → 执行改签
|
||||
}
|
||||
|
||||
void passengerViewOrders() {
|
||||
// TODO: 交互:输入身份证号 → 显示该乘客所有订单
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* order.h - 购票/退票/改签模块(订单管理)
|
||||
* 负责人:组员B
|
||||
*
|
||||
* 核心数据结构:候补队列 WaitQueue(队列)
|
||||
* C++ 版本
|
||||
*/
|
||||
|
||||
#ifndef ORDER_H
|
||||
#define ORDER_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/* ==================== 候补队列结构 ==================== */
|
||||
|
||||
struct WaitQueue {
|
||||
OrderInfo data[MAX_QUEUE_SIZE];
|
||||
int front = 0; // 队首下标
|
||||
int rear = 0; // 队尾下标
|
||||
int count = 0; // 当前队列长度
|
||||
};
|
||||
|
||||
/* ==================== 队列操作 ==================== */
|
||||
|
||||
void InitQueue(WaitQueue& Q);
|
||||
bool EnQueue(WaitQueue& Q, const OrderInfo& e);
|
||||
bool DeQueue(WaitQueue& Q, OrderInfo& e);
|
||||
bool QueueEmpty(const WaitQueue& Q);
|
||||
bool QueueFull(const WaitQueue& Q);
|
||||
|
||||
/* ==================== 订单操作 ==================== */
|
||||
|
||||
// 生成订单号(自增格式化)
|
||||
string GenerateOrderId();
|
||||
|
||||
// 购票
|
||||
int BuyTicket(const OrderInfo& order);
|
||||
|
||||
// 退票(若有候补自动转正)
|
||||
int RefundTicket(const string& orderId);
|
||||
|
||||
// 改签
|
||||
int ChangeTicket(const string& orderId, const string& newTrainNo);
|
||||
|
||||
// 按身份证号查询订单,返回匹配数量
|
||||
int SearchOrdersByIdCard(const string& idCard,
|
||||
OrderInfo results[], int maxResults);
|
||||
|
||||
// 按订单号查询
|
||||
const OrderInfo* SearchOrderById(const string& orderId);
|
||||
|
||||
/* ==================== 文件读写 ==================== */
|
||||
|
||||
int loadOrdersFromFile(const string& filename);
|
||||
int saveOrdersToFile(const string& filename);
|
||||
|
||||
/* ==================== 乘客接口 ==================== */
|
||||
|
||||
void passengerBuyTicket();
|
||||
void passengerRefundTicket();
|
||||
void passengerChangeTicket();
|
||||
void passengerViewOrders();
|
||||
|
||||
#endif /* ORDER_H */
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* stack.cpp - 操作撤销栈模块实现
|
||||
* 负责人:组员B
|
||||
*
|
||||
* TODO: 组员B 请在此文件中实现所有声明的函数
|
||||
* C++ 版本
|
||||
*/
|
||||
|
||||
#include "stack.h"
|
||||
#include "order.h" // 需要调用 RefundTicket / BuyTicket 执行逆操作
|
||||
|
||||
/* ==================== 全局变量 ==================== */
|
||||
|
||||
OpStack undoStack;
|
||||
|
||||
/* ==================== 栈操作 ==================== */
|
||||
|
||||
void InitStack(OpStack& S) {
|
||||
// TODO: top = -1
|
||||
}
|
||||
|
||||
bool Push(OpStack& S, const OperationLog& op) {
|
||||
// TODO: 检查栈满 → false
|
||||
// top++,data[top] = op
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Pop(OpStack& S, OperationLog& op) {
|
||||
// TODO: 检查栈空 → false
|
||||
// op = data[top],top--
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StackEmpty(const OpStack& S) {
|
||||
// TODO: top == -1
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StackFull(const OpStack& S) {
|
||||
// TODO: top == MAX_STACK_SIZE - 1
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ==================== 撤销功能 ==================== */
|
||||
|
||||
int ExecuteUndo(OpStack& S) {
|
||||
// TODO:
|
||||
// 1. Pop 出一个 OperationLog
|
||||
// 2. 根据其 type 执行逆操作:
|
||||
// BUY → 调用 RefundTicket
|
||||
// REFUND → 调用 BuyTicket(恢复原订单)
|
||||
// CHANGE → 改回原车次
|
||||
// 3. 注意:撤销操作本身不再次入栈
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ==================== 乘客接口 ==================== */
|
||||
|
||||
void passengerUndo() {
|
||||
// TODO:
|
||||
// 1. 判断 undoStack 是否为空
|
||||
// 2. 显示最近操作信息,询问是否确认撤销
|
||||
// 3. 执行 ExecuteUndo
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* stack.h - 操作撤销栈模块
|
||||
* 负责人:组员B
|
||||
*
|
||||
* 核心数据结构:顺序栈 OpStack
|
||||
* 功能:记录最近操作,支持撤销购票/退票/改签
|
||||
* C++ 版本
|
||||
*/
|
||||
|
||||
#ifndef STACK_H
|
||||
#define STACK_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/* ==================== 栈结构 ==================== */
|
||||
|
||||
struct OpStack {
|
||||
OperationLog data[MAX_STACK_SIZE];
|
||||
int top = -1; // 栈顶下标,-1 表示栈空
|
||||
};
|
||||
|
||||
/* ==================== 栈操作 ==================== */
|
||||
|
||||
void InitStack(OpStack& S);
|
||||
bool Push(OpStack& S, const OperationLog& op);
|
||||
bool Pop(OpStack& S, OperationLog& op);
|
||||
bool StackEmpty(const OpStack& S);
|
||||
bool StackFull(const OpStack& S);
|
||||
|
||||
/* ==================== 撤销功能 ==================== */
|
||||
|
||||
// 执行撤销(调用对应的逆操作)
|
||||
// 购票→退票,退票→购票,改签→改回原车次
|
||||
int ExecuteUndo(OpStack& S);
|
||||
|
||||
/* ==================== 乘客接口 ==================== */
|
||||
|
||||
void passengerUndo();
|
||||
|
||||
#endif /* STACK_H */
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* train.cpp - 车次信息管理模块实现(顺序表)
|
||||
* 负责人:组员A
|
||||
*
|
||||
* TODO: 组员A 请在此文件中实现所有声明的函数
|
||||
* C++ 版本
|
||||
*/
|
||||
|
||||
#include "train.h"
|
||||
|
||||
/* ==================== 全局变量 ==================== */
|
||||
|
||||
TrainList trainList;
|
||||
|
||||
/* ==================== 基础操作 ==================== */
|
||||
|
||||
bool ListInsert(TrainList& L, int i, const TrainInfo& e) {
|
||||
// TODO: 在位置 i 插入车次
|
||||
// 检查合法性(i 范围、表是否满、车次号是否重复)
|
||||
// 将位置 i 及之后元素后移一位
|
||||
// 插入新元素,length++
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ListDelete(TrainList& L, int i, TrainInfo& e) {
|
||||
// TODO: 删除位置 i 的车次,结果存入 e
|
||||
// 将位置 i+1 及之后元素前移一位
|
||||
// length--
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ListUpdate(TrainList& L, int i, const TrainInfo& e) {
|
||||
// TODO: 更新位置 i 的车次信息
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ==================== 查找算法 ==================== */
|
||||
|
||||
int SeqSearch(const TrainList& L, const string& trainNo) {
|
||||
// TODO: 顺序查找,逐个比较 trainNo
|
||||
// 找到返回下标,未找到返回 -1
|
||||
return -1;
|
||||
}
|
||||
|
||||
int BinSearch(const TrainList& L, const string& trainNo) {
|
||||
// TODO: 二分查找(前提:顺序表按 trainNo 有序)
|
||||
// 使用 InsertSort 排序后再查找
|
||||
return -1;
|
||||
}
|
||||
|
||||
int SearchByStation(const TrainList& L, const string& keyword,
|
||||
TrainInfo results[], int maxResults) {
|
||||
// TODO: 按站名模糊查找(在 startStation / endStation 中匹配)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AdvancedSearch(const TrainList& L, const string& startStation,
|
||||
const string& endStation, float minPrice,
|
||||
float maxPrice, TrainInfo results[], int maxResults) {
|
||||
// TODO: 多条件组合查询
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ==================== 排序算法 ==================== */
|
||||
|
||||
void InsertSort(TrainList& L) {
|
||||
// TODO: 直接插入排序(按车次号升序)
|
||||
// 将 trainNo 字符串比较,从小到大排列
|
||||
}
|
||||
|
||||
void QuickSort(TrainList& L, int low, int high) {
|
||||
// TODO: 快速排序(按票价排序)
|
||||
}
|
||||
|
||||
void HeapSort(TrainList& L) {
|
||||
// TODO: 堆排序(按余票数排序)
|
||||
// 构建大顶堆 / 小顶堆
|
||||
}
|
||||
|
||||
/* ==================== 文件读写 ==================== */
|
||||
|
||||
int loadTrainsFromFile(const string& filename) {
|
||||
// TODO: 用 ifstream 读取 CSV 文件
|
||||
// 跳过标题行,逐行解析字段填充 TrainInfo
|
||||
// 存入 trainList
|
||||
return 0;
|
||||
}
|
||||
|
||||
int saveTrainsToFile(const string& filename) {
|
||||
// TODO: 用 ofstream 写回 CSV 文件
|
||||
// 先写标题行,再逐行输出 trainList 数据
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ==================== 管理员接口 ==================== */
|
||||
|
||||
void adminAddTrain() {
|
||||
// TODO: 交互式录入新 TrainInfo,调用 ListInsert
|
||||
}
|
||||
|
||||
void adminDeleteTrain() {
|
||||
// TODO: 输入车次号,SeqSearch 找到后调用 ListDelete
|
||||
}
|
||||
|
||||
void adminModifyTrain() {
|
||||
// TODO: 查找后修改字段,调用 ListUpdate
|
||||
}
|
||||
|
||||
void adminListTrains() {
|
||||
// TODO: 遍历 trainList 输出所有车次
|
||||
}
|
||||
|
||||
void adminSearchTrain() {
|
||||
// TODO: 提示选择查找方式(顺序/二分/站名模糊)
|
||||
}
|
||||
|
||||
void adminSortTrains() {
|
||||
// TODO: 提示选择排序方式(票价快排 / 余票堆排)
|
||||
}
|
||||
|
||||
void adminShowStatistics() {
|
||||
// TODO: 调用 hash 模块的统计函数展示
|
||||
}
|
||||
|
||||
/* ==================== 乘客接口 ==================== */
|
||||
|
||||
void passengerSearchTrain() {
|
||||
// TODO: 乘客查车次(支持按站名、时间、票价区间筛选)
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* train.h - 车次信息管理模块(顺序表)
|
||||
* 负责人:组员A
|
||||
*
|
||||
* 核心数据结构:顺序表 TrainList
|
||||
* 算法:顺序查找、二分查找、直接插入排序、快速排序、堆排序
|
||||
* C++ 版本
|
||||
*/
|
||||
|
||||
#ifndef TRAIN_H
|
||||
#define TRAIN_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/* ==================== 顺序表结构 ==================== */
|
||||
|
||||
struct TrainList {
|
||||
TrainInfo data[MAX_TRAINS];
|
||||
int length = 0;
|
||||
};
|
||||
|
||||
/* ==================== 基础操作 ==================== */
|
||||
|
||||
// 增:在位置 i 插入车次
|
||||
bool ListInsert(TrainList& L, int i, const TrainInfo& e);
|
||||
|
||||
// 删:删除位置 i 的车次,将删除的元素存入 e
|
||||
bool ListDelete(TrainList& L, int i, TrainInfo& e);
|
||||
|
||||
// 改:更新车次信息
|
||||
bool ListUpdate(TrainList& L, int i, const TrainInfo& e);
|
||||
|
||||
/* ==================== 查找算法 ==================== */
|
||||
|
||||
// 顺序查找(按车次号),返回下标,未找到返回 -1
|
||||
int SeqSearch(const TrainList& L, const string& trainNo);
|
||||
|
||||
// 二分查找(要求顺序表按 trainNo 有序),返回下标,未找到返回 -1
|
||||
int BinSearch(const TrainList& L, const string& trainNo);
|
||||
|
||||
// 按始发站/终点站模糊查找,返回匹配数量
|
||||
int SearchByStation(const TrainList& L, const string& keyword,
|
||||
TrainInfo results[], int maxResults);
|
||||
|
||||
// 多条件组合查询
|
||||
int AdvancedSearch(const TrainList& L, const string& startStation,
|
||||
const string& endStation, float minPrice,
|
||||
float maxPrice, TrainInfo results[], int maxResults);
|
||||
|
||||
/* ==================== 排序算法 ==================== */
|
||||
|
||||
// 直接插入排序(按车次号排序)
|
||||
void InsertSort(TrainList& L);
|
||||
|
||||
// 快速排序(按票价排序)
|
||||
void QuickSort(TrainList& L, int low, int high);
|
||||
|
||||
// 堆排序(按余票数排序)
|
||||
void HeapSort(TrainList& L);
|
||||
|
||||
/* ==================== 文件读写 ==================== */
|
||||
|
||||
int loadTrainsFromFile(const string& filename);
|
||||
int saveTrainsToFile(const string& filename);
|
||||
|
||||
/* ==================== 管理员接口 ==================== */
|
||||
|
||||
void adminAddTrain();
|
||||
void adminDeleteTrain();
|
||||
void adminModifyTrain();
|
||||
void adminListTrains();
|
||||
void adminSearchTrain();
|
||||
void adminSortTrains();
|
||||
void adminShowStatistics();
|
||||
|
||||
/* ==================== 乘客接口 ==================== */
|
||||
|
||||
void passengerSearchTrain();
|
||||
|
||||
#endif /* TRAIN_H */
|
||||
Reference in New Issue
Block a user