[英]C Code: Efficient way to parse through to end of LinkedList
我有一个结构数据,这将是消息的链接列表。 对于每条新消息,我都需要在链接列表的最后添加。 我有一个柜台,我知道那里有多少条消息。 而不是解析到链接列表的末尾。 有没有更好的方法可以到达链接列表中的特定位置?
struct Data {
char *message;
struct Data *next;
}data;
int total_message;
现在我解析如下:
struct Data *traverse;
while(traverse->next != NULL)
traverse = traverse->next;
我也在下面尝试过,我不确定为什么从逻辑上讲这对我来说似乎是正确的。
data[total_messages - 1].next = new_data;
除了存储指向“上一条消息”的指针之外,还有什么更好的方法吗?
考虑维护一个指向链表尾部的指针。
data * head = NULL;
data * tail = NULL;
void Append(data * entry) {
if (!head) {
head = entry;
}
if (tail) {
tail->next = entry;
}
tail = entry;
}
为什么遍历(如问题所示)不好?
如果我们仅保持head
且消息数为n
,则对于每个追加,我们都必须遍历从head
开始的n
链接节点-这是O(n)
操作-效率低下。 如果添加到列表的尾部是一项频繁的操作(如您所见),那么维护尾部指针将非常有效。 在空间上,维护计数器与维护指针相同。
为什么以下情况不好?
data[total_messages - 1].next = new_data;
那是一个数组符号。 数组是连续的内存块。 在链表中,节点可以在内存中的任何位置,无法以这种数组表示法进行访问。
[]
语法适用于数组,因为数组以可预测的方式将数据排列在一行中。 链接列表没有。 您只能通过跟随next
指针来找出第ith个元素的位置。
data[i]
是指i
放置在内存地址data
之后的data
,该data
不太可能位于Data结构的位置。 将数据写入该位置通常只会破坏程序中其他位置的随机代码部分。
一种快速且相对简单的解决方案是在解析时将每个新元素推到列表的最前面 ,然后在推完所有元素后将列表反转到位。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.