Операция удаления работает похоже. Например, из связного списка нужно удалить третий элемент. Тогда переставляем указатель второго на четвёртый, если в списке больше трёх элементов. Если в списке три элемента, поставим указатель второго элемента на None либо аналогичный объект, в зависимости от языка программирования.
Чтобы представить эту структуру данных в С++, можно применять структуры, а в Python — классы. Рассмотрим код на Python.
Скопировать кодPYTHON
class Node:
def __init__(self, value = None, next = None):
self.value = value
self.next = next
def __str__(self):
return self.value
У каждого элемента есть значение и ссылка на следующий элемент списка.
Метод str в Python определяет, что будет выведено при вызове функции print(). Тут мы его применяем для удобства. Он помогает выводить значение поля value в удобном формате. Метод str или аналогичный в другом языке программирования определять необязательно.
Создадим три элемента:
Скопировать кодPYTHON
n3 = Node('third')
n2 = Node('second', n3)
n1 = Node('first', n2)
Получили связный список из трёх элементов. Первый ссылается на второй:
Скопировать кодPYTHON
print(n1.next)
Второй ссылается на третий, а третий — на None:
Скопировать кодPYTHON
print(n3.next)
Так можно представлять связный список. Напишем функцию добавления нового элемента в связный список:
Скопировать кодPYTHON
def insert_node(node, index, value):
head = node
new_node = Node(value)
if index == 0:
new_node.next = node
return new_node
while index-1:
node = node.next
index -= 1
tmp = node.next
node.next = new_node
new_node.next = tmp
return head
Что происходит в коде этой функции?
На вход она принимает голову списка, индекс, по которому вы хотите добавить элемент, и значение нового элемента. Возвращать функция будет голову списка.
Запомним голову списка в переменной head, чтобы потом вернуть её из функции. Сначала создадим объект класса Node из добавляемого элемента, так как все элементы в списке должны иметь два поля: значение и ссылку на соседа. Это нам и обеспечит класс Node.
Как вы, вероятно, догадались, нужно найти элемент, за которым хотим вставить новый, и переместить его указатель на вставляемый элемент. Новый элемент должен указывать на прошлого соседа того элемента, после которого мы сделали вставку.
Отдельно нужно обработать случай, когда хотим вставить элемент в голову списка, так как на неё никакой элемент не указывает. Добавляем новый элемент в качестве головы списка. Он будет ссылаться на предыдущую голову.
На первой итерации цикла переменная index-1 будет равна 1, и мы переместимся вправо на элемент с индексом 1. После этого элемента мы и хотим добавить новый. На второй итерации переменная index-1 будет равна 0, блок кода внутри цикла выполняться не будет. Как раз это нам и нужно, так как до нужной позиции мы уже дошли.
Затем меняем указатели. Элемент, на который указывал найденный объект, запомним во временную переменную. Это нужно сделать, потому что мы переставим указывающую на него ссылку. А терять этот элемент нельзя, ведь на него будет указывать вставляемый элемент. Поменяв ссылки, можем вернуть голову списка из функции.
Вставим элемент со значением 'new_node' на позицию 2:
Скопировать кодPYTHON
node, index, value = n1, 2, 'new_node'
head = insert_node(node, index, value)
Посмотрим на голову списка. Она не изменилась.
Скопировать кодPYTHON
print(head)
Элемент на позиции 1 также остался прежним.
Скопировать кодPYTHON
print(head.next)
А вот элемент на позиции 2 поменялся. Теперь там объект класса Node со значением 'new_node', как мы и хотели.
Скопировать кодPYTHON
print(head.next.next)
Запустите код с различными параметрами функции и посмотрите, что будет происходить.
Односвязный список — очень удобная структура данных, ведь в неё можно вставлять и удалять элементы очень эффективно.
Но получить доступ к элементу по индексу при использовании односвязного списка нельзя.