【发布时间】:2021-01-26 08:14:50
【问题描述】:
任务是编写双向链表的序列化和反序列化函数(不使用第三方库和标准序列化工具),以这种形式呈现:
class ListNode
{
public ListNode Previous;
public ListNode Next;
public ListNode Random;
public string Data;
}
class ListRandom
{
public ListNode Head;
public ListNode Tail;
public int Count;
}
其中public ListNode Random 是对列表中随机项的引用。
我原来的解决方案是这样的:
class ListRandom
{
public ListNode Head;
public ListNode Tail;
public int Count;
private ListNode GetNodeAt(int index)
{
int counter = 0;
for (ListNode currentNode = Head; currentNode.Next != null; currentNode = currentNode.Next)
{ if (counter == index)
return currentNode;
counter++;
}
return new ListNode();
}
public void Serialize(Stream s)
{
Dictionary<ListNode, int> dictionary = new Dictionary<ListNode, int>();
int id = 0;
for (ListNode currentNode = Head; currentNode != null; currentNode = currentNode.Next)
{
dictionary.Add(currentNode, id);
id++;
}
using (BinaryWriter writer = new BinaryWriter(s))
{
for (ListNode currentNode = Head; currentNode != null; currentNode = currentNode.Next)
{
writer.Write(currentNode.Data);
writer.Write(dictionary[currentNode.Random]);
}
}
Console.WriteLine("List serialized");
}
public void Deserialize(Stream s)
{
Dictionary<int, Tuple<String,int>> dictionary = new Dictionary<int, Tuple<String, int>>();
int counter = 0;
using (BinaryReader reader = new BinaryReader(s))
{
while (reader.PeekChar() != -1)
{
String data = reader.ReadString();
int randomId = reader.ReadInt32();
dictionary.Add(counter, new Tuple<String, int>( data, randomId));
counter++;
}
Console.WriteLine("File readed");
}
Count = counter;
Head = new ListNode();
ListNode current = Head;
for (int i = 0; i < Count; i++)
{
current.Data = dictionary.ElementAt(i).Value.Item1;
current.Next = new ListNode();
if (i != this.Count - 1)
{
current.Next.Previous = current;
current = current.Next;
}
else
{
Tail = current;
}
}
counter = 0;
for (ListNode currentNode = Head; currentNode.Next != null; currentNode = currentNode.Next)
{
currentNode.Random = GetNodeAt(dictionary.ElementAt(counter).Value.Item2);
counter++;
}
Console.WriteLine("List deserialized");
}
算法如下 - 序列化时,首先我遍历列表,并从列表的一个元素和一个数字创建一个字典,它将描述该元素在列表中的索引。接下来,我正在编写到节点的文件数据,以及 ListNode Random 引用的列表项的编号。 反序列化时,我从一个数字(列表的未来元素的索引)和一对 String(元素的数据)和 int(ListNode Random 将引用的列表元素的索引)创建一个字典。接下来,我正在创建列表本身,用数据填充它,但没有为 ListNode Random 分配任何值,因为它可以引用目前不存在的元素。并在最后一个循环中,为每个 ListNode Random 分配所需的链接到列表项。
如何改进此代码/算法?
【问题讨论】:
标签: c# serialization deserialization doubly-linked-list