任何一种方式都可以,但出于性能原因,通常首选在前面插入。
插入一个新元素作为头部非常快,O(1),因为你只需要创建一个元素和一个指向旧头部的指针。
在末尾插入意味着遍历列表以找到最后一个元素并更新它指向新元素的指针。这是 O(n)。
您也可以通过跟踪列表的尾部并在末尾进行 O(1) 插入来交换存储时间。但是你得到的东西比单链表要复杂一些。
通常符合条件
当我说通常时,我指的是手工制作的单链表,尤其是用 C 语言编写的,可能适用于一些空间非常宝贵并且需要额外空间来存储尾部的嵌入式设备实在是太多了。
对于像 Java 这样的通用语言,LinkedList 实现存储尾部,因此两个操作都是 O(1)。有趣的是,在 Java 案例中,List 的抽象接口只定义了一个追加到列表的操作。
实现(伪 C 语言)
假设我有一些列表,例如
struct List {
int data;
List *next;
};
如果我想在开头插入,我会写
List* insert(List *original_list, int data) {
List* head = allocate new List(data, original_list);
return head;
}
如果我想追加,我会写
void append(List *original_list, int data) {
List* new_tail = allocate new List(data, null);
ptr = original_list
while(ptr->next != null)
ptr++
ptr->next = new_tail;
}