储存信息为索引和数据两部分组成
模板:
template <class Key,class Data>其在叶结点文件中位置和父亲、左右兄弟在文件中位置;
int position = -1;
int father = -1;
int leftPos = -1;
int rightPos = -1;储存数据数量;
int dataSize = 0;索引数组(最大容量为L),数据数组(最大容量为L);
Key KEY[L];
Data DATA[L];添加数据函数(addElement),若达到L条数据,则进行裂块(split);
删除数据函数(deleteElement),若小于L/2条数据,则分情况进行:
左借(borrowLeft),右借(borrowRight),左合并(mergeLeft),右合并(mergeRight);
查找数据函数(findElement):在引用的vector中储存与特定索引(_key)相关的数据;
查找删除位置(findDeletePos);(服务于可重复索引的bpt)
查找下一条数据(findNextElement):查找特定索引的下一个索引的数据;(服务于储存不可重复索引的bpt);
其在非叶结点文件中位置和父亲、左右兄弟在文件中位置;
int position = -1;
int father = -1;
int leftPos = -1;
int rightPos = -1;子结点数量;
int childSize = 0;索引数组(最大数量M - 1);
Key INDEX[M];子结点在文件中位置,若儿子为叶结点,则为在叶节点文件中位置(最大数量M);
int childPosition[M];表示子结点是否为叶结点的布尔值;
bool childIsLeaf = false;添加数据函数(addElement),若达到M个子结点,则进行裂块(split);
删除数据函数(deleteElement),若小于M/2个子结点,则分情况进行:
左借(borrowLeft),右借(borrowRight),左合并(mergeLeft),右合并(mergeRight);
查找索引位置函数(findKeyPos);
根结点在非叶结点文件中位置;
储存数据量(叶结点数);
最左(最小key)叶结点在叶结点文件中位置,即叶结点链表表头;
int root = -1;
int size = 0;
int head = -1;设置基本信息(setInfo);
void setInfo(int _root,int _head,int _size){
root = _root,head = _head,size = _size;
}在叶结点链表内的迭代器,实现++、--,可返回当前数据信息的key和data,以及可以知道是否在表头或表尾。
basicInfo BasicInformation;
//基本信息储存入非叶结点文件中
DiskExe<leafNode,basicInfo> leafDisk;
DiskExe<nonLeafNode,basicInfo> nodeDisk;
//bonus内容:B+树回收池
recyclePool repos;需给出文件名_name
非叶结点文件名为 "_name_node.dat"
叶结点文件名为 "_name_leaf.dat"
explicit BPT(const string & _name):leafDisk(_name + "_leaf.dat",379),nodeDisk(_name + "_node.dat",15372)
{
BasicInformation = nodeDisk.tellInfo();
}重新在非叶结点文件头设置基本信息
~BPT(){nodeDisk.setInfo(BasicInformation);}-
size()返回bpt大小;
-
empty()返回布尔值表示bpt是否为空;
-
//插入函数,给出索引和储存信息,将其作为数据块插入bpt中 void insert(const Key & _key,const Data & _data);
-
//删除函数,给出索引和储存信息,若在bpt中存在该数据块则将其删除,返回true,反之返回false bool erase(const Key & _key,const Data & _data);
-
//查找函数,给出索引,将所有该索引连结的数据储存如引用的vector中 void find(const Key & _key,vector<Data> & vec_ans);
-
//对于储存不可重复key的bpt,给出一个索引,找到下一索引的数据,返回pair //second == 0:未找到;second == 1: 已找到;second == 2: end pair<Data,int> NextData(const Key & _key);
-
begin(): 返回一个指向叶结点表头的iterator;
-
clear(): 清除bpt内文件,重置其信息;
-
findAll(): 将所有数据存入引用容器中(数据量过大时不建议使用);
文件流对象,文件名;
文件链表当前位置与预处理位置:节省存储空间;
缓存链表,辅助哈希表;
将文件中内容作为数据块读入内存,以链表形式存储;
链表容量一定,每次插入至表头,并弹出表尾元素;
保证可能多次使用的数据块更新至表头;
析构时将缓存内容全部写入文件。
//在文件尾或者文件回收位置写入data
int write(const T & data);//在指定位置写入*data
void write(const T * data,int position);//从指定位置读入类型为T的数据
T * read(int index);-
tellp():返回文件尾位置;
-
//在表头设置基本信息(bpt) void setInfo(const basicInfo & info);
-
clear(): 清空并重置文件;
参考STLite中vetor,使用方法类同stl库;
哈希表使用头文件中hash以给索引key分配相应位置。
void insert(const Key & _key,const Data & _data);Data & find(const Key & _key);void erase(const Key & _key);Data & operator [](const Key & _key);void clear();- _username char数组,储存用户名
- _password char数组,储存密码
- _mailAddr char数组,储存邮箱地址
- _name char数组,储存中文名
- _privilege(int),储存优先级
- _login(int),记录是否已经登录 0:未登录 1:已登录
- hsh(unsigned int) 记录用户名的哈希值
- name char数组,记录车站名
- hsh(unsigned int),记录车站名哈希值
- _trainID char数组,记录Train的ID
- int _stationNum 记录经过车站数
- int _seatNum 记录座位数
- int _prices 记录车票价格
- int _travelTimes 记录相邻两个站之间行驶时间
- int _stopoverTimes 记录在一个站停留的时间
- station _stations 记录经过的车站
- char _type 记录列车类型
- std::pair<int,int> _st,_ed 记录列车运行的时间段
- std::pair<int,int> _starttime 记录列车每天发车时间
- int released 记录列车状态 0:未发布 1:已发布 -1:删除
- int _ticketsSold[96] 被售出的车票数
- std::pair<int,int> tim[105][2] 记录到达每个站和从某个站出发的时间
- int g[105][2]; 记录到达每个站和从每个站出发的日期和发车日期间隔的天数
- data pair<int,int> 记录订单的购买的车票的发车时间
- user_id train_id unsigned int 记录订单的购买用户和火车车次
- Num status 购买车票数量和订单状态
- l,r int 记录出发站和到达站
- price long long 记录车票价格
设计整体思想: 使用b+树维护火车信息用户信息订单信息在文档中的位置
BPT: BPT<uint,int> mp("User_bpt"); 维护用户信息在文件中的位置 BPT<std::pair<uint,int>,int> Order_mp("Order_bpt"),Wait_mp("Wait_bpt"); 维护订单信息和候补订单信息在文件中的位置 BPT<uint,int> Station_mp("Station_bpt"); 车站信息在文件中的位置 BPT<uint,int> mp_Train("Train_bpt"); 维护火车信息在文件中的位置
文件: User:储存用户信息
Train:储存火车信息
Order:储存订单信息
Seat:储存每天班次车辆卖出的车票数量
Station:记录每个站台经过的火车信息
函数: int main():分配指令
void create_file():建立文件
inline uint gethsh(char *ch) 求ch哈希值
inline bool pd (std::pair<int,int> st,std::pair<int,int> ed,std::pair<int,int> tmp)判断tmp是否在st到ed之间
void T_read(int pos,T &a) 从文件pos位读取信息存到a中
int T_write(int pos,T &a) 将a储存到文件从pos位开始
int add_user():添加用户
int login():登录
int logout():登出
int query_profile():查询用户信息
int modify_profile():修改用户信息
int add_train():添加车辆
int release_train():发布车辆
int query_train():查询车辆
int delete_train():删除车辆
void query_ticket():查询车票 找到同时经过出发站终点站的列车,查看是否满足要求,若满足加入答案,最后将答案排序输出
void query_transfer():查询换乘 先枚举第一辆车,再枚举中间站,再枚举第二辆车,第二辆车必须同时经过中间站和终点站
long long buy_ticket():买票
int query_order():查询订单 通过Order_mp查询
int refund_ticket():退票 通过Order_mp查询修改,若退票成功,再检查该列车是否可以进行补票
void clean():清空