I tried to serialize a doubly linked list. Can you rate it, and what could be improved?
I open the file with fopen(path, "wb") and write all data in binary mode.
#include <string>
#include <unordered_map>
#include <vector>
#include <random>
#include <iostream>
struct ListNode {
ListNode* prev = nullptr;
ListNode* next = nullptr;
ListNode* rand = nullptr;
std::string data;
};
class List {
public:
void Serialize(FILE* file)
{
std::unordered_map<ListNode*, int> uMap;
auto cur = head;
for (int i = 1; i <= count; i++)
{
uMap.insert(std::make_pair(cur, i));
cur = cur->next;
}
std::vector <std::pair<std::string, int>> vNode;
vNode.reserve(count);
cur = head;
while (cur)
{
int randEl{ 0 };
if (cur->rand != nullptr)
{
auto search = uMap.find(cur->rand);
randEl = search->second;
}
vNode.push_back(std::make_pair(cur->data, randEl));
cur = cur->next;
}
fwrite(&count, sizeof(count), 1, file);
for (auto& a: vNode)
{
fwrite(&a.second, sizeof(a.second), 1, file);
int size = a.first.size();
fwrite(&size, sizeof(size), 1, file);
fwrite(a.first.c_str(), 1, size, file);
}
}
void Deserialize(FILE* file)
{
std::unordered_map<int, ListNode*> uMap;
std::vector<int> vRandNode;
int rCount{ 0 };
fread(&rCount, sizeof(rCount), 1, file);
vRandNode.reserve(rCount);
rCount = 1;
for (; rCount <= vRandNode.capacity(); rCount++)
{
int randNode{ 0 };
fread(&randNode, sizeof(randNode), 1, file);
int len{ 0 };
fread(&len, sizeof(len), 1, file);
std::string temp{ "" };
while (len > 0)
{
char ch ;
fread(&ch, sizeof(ch), 1, file);
temp += ch;
len--;
}
Add(temp);
vRandNode.push_back(randNode);
uMap.insert(std::make_pair(rCount, tail));
}
auto cur = head;
for(auto a: vRandNode)
{
if (a != 0)
cur->rand = uMap.find(a)->second;
else
cur->rand = nullptr;
cur = cur->next;
}
}
void Add(std::string str)
{
ListNode* node = new ListNode;
node->data = std::move(str);
count++;
if (head == nullptr)
{
head = node;
}
else
{
tail->next = node;
node->prev = tail;
}
tail = node;
}
List(){}
List(std::string str)
{
Add(std::move(str));
}
~List()
{
while (head)
{
auto temp = head->next;
delete head;
head = temp;
}
}
void ShufleRandom()
{
std::random_device rd;
std::mt19937 gen(rd());
auto cur = head;
while (cur)
{
auto randNode = head;
int randNum = gen() % (count + 1);
for (int i = 1; i < randNum; i++)
{
randNode = randNode->next;
}
if (randNum == 0)
cur->rand = nullptr;
else
cur->rand = randNode;
cur = cur->next;
}
}
void PrintListAndRand() const
{
auto cur = head;
while (cur)
{
std::cout << "===Data->" << cur->data;
if (cur->rand)
std::cout << " | RandData->" << cur->rand->data << "===" << std::endl;
else
std::cout << " | RandData->nullptr===" << std::endl;
cur = cur->next;
}
std::cout << "_______________________________________________________________" << std::endl;
}
private:
ListNode* head = nullptr;
ListNode* tail = nullptr;
int count = 0;
};