Возможен любой способ, но вставка спереди обычно предпочтительнее по соображениям производительности.
Вставка нового элемента в качестве заголовка очень быстрая, 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;
}