Лекции / Лекция_8_Структуры_данных_ipynb_Colab (1)
.pdf
Добавление значения в конец списка. Список не пуст
Добавление значения в произвольное место списка
Удаление значения из начала списка
Установить значение head равное значению next удаляемого элемента. Указать, значение next удаляемого узла равным null. Освободить память занимаемую удаляемым узлом.
Удаление элемента из конца списка
Удаление элемента из произвольного места списка
Получение размера списка
Для получения размера списка стоит объявить переменную с начальным значением 0. Начиная с начала списка выполнять переход по ссылке к следующему узлу. На каждом переходе увеличивать значение этой переменной на 1. Закончить на узле для которого next == null.
Работа с индексами
Для работы с индексами можно использовать подход аналогичный вычислению длинны. Стоит объявить переменную начальное значение которой равно начальному индексу (произвольный выбор). Начиная с головы списка выполняем проход по next (от узла к узлу), то тех пор пока значение этой переменной не станет равно искомому индексу
Реализация на Python
Описание узла,списка и методы добавления
class Node: |
|
|
def __init__(self, data=None, next=None): |
|
|
#Инициалиузлаациясохраняем: данныеиссылкуна |
следующийузел |
|
self.data=data |
|
|
self.next=next |
|
|
def __str__(self): |
|
|
#Припреобразованиистрокувозвращаемданные |
узла(опечаткаdate-:data)> |
|
return str(self.data) |
|
|
class LinkedList: |
|
|
def __init__(self): |
|
|
#Присозданииспискаголовапуста(списокне |
содержитузлов) |
|
self.head= |
None |
|
def add_first(self, value):
# Создаём новый узел с переданным значением
new_node=Node (value)
#Новыйузелуказывнатекущуюетголовусписка new_node=.next self.head
#Головойспискастановитсяновыйузел self.head=new_node
def add_last(self, value):
#Создаёмновыйузелспереданнымзначением new_node=Node (value)
#Еслисписокпустновый, узелстановитсяголовой if self.head is None:
self.head=new_node return
#Начинаемобходсголовысписка |
|
|
|
current=_node |
self.head |
|
|
#Идёмдопоследнегоузла(укоторогоnext== |
None) |
|
|
while current_node.next |
is not None: |
|
|
current=_currentnode_node.next |
|
|
|
#Присоединяемновыйузелвконец |
|
|
|
current_node=new.nextnode |
|
|
|
current=_currentnode_node.next |
#этастроканенужнаоставлена, длясовместимости |
сисходнымкодом |
|
Методы удаления
def delete_last(self):
#Еслисписокпустилисодержиттолькоодинузел
if self.head is None or self.head.next is None:
self.head= |
None |
#Обнуляемголову(спистановитсяокпустым) |
|||
return |
|
|
|
|
|
#Начинаемобходсголовы |
|
|
|
|
|
current=_node |
self.head |
|
|
||
previous=currnodent_node |
|
|
|
||
#Идёмдопоследнегоузла(укоторогоnext== |
|
None) |
|||
while current_node.next |
is not None: |
|
|||
previous=currentnode _node |
|
|
#Запоминаемпредыдущийузел |
||
current=_currentnode_node.next |
|
#Переходимкследующему |
|||
#Послециклаcurrentуказывnodeнапоследнийет |
узел |
||||
#previousуказывnodeнапредпоследнийетузел |
|
|
|||
previous_node=.next |
None |
#Отвязываемпоследнийузел |
|||
def delete_first(self): |
|
|
|
||
#Еслисписокпустничего, неделаем |
|
|
|
||
if self.head is None: |
|
|
|
||
return |
|
|
|
|
|
#Удаляпемрвыйузелперемещая, головуна |
|
|
следующийузел |
||
self.head= |
self.head.next |
|
|
||
Методы для работы с индексами
def insert_by_index(self, value, index): |
|
||
#Есливставляемначалосписка(индекс0) |
|
|
|
if index== |
0: |
|
|
self.add_first(value) |
#Используемготовыйметоддобавленияначало |
|
|
return |
|
|
|
#Создаёмновыйузелспереданнымзначением |
|
|
|
new_node=Node(value) |
|
|
|
node_number= |
1 |
#Номертекущегоузла(начинаемс1,таккак |
index=0ужеобработан) |
current=_node |
self.head |
#Начинаемобходсголовысписка |
|
#Идёмпоспискупока,недойдёмконца
while current_node is not None:
#Еслинашлипозициюдлявставки if index==node_number:
#Новыйузелуказывнаследующийетпосле currentузелnode new_node=current.next _node.next
#Текущийузелначинаетуказывнановыйтьузел current_node= .wnextnode
return
#Переходимкследующемуузлу current=_currentnode_node.next node_number+= 1
def delete_by_index(self, index): |
|
|
|||
#Еслиудаляпервыймэлемент(индекс0) |
|
|
|
||
if index== |
0: |
|
|
|
|
self.delete_first() |
#Используемготовыйметодудаленияпервого |
элемента |
|||
return |
|
|
|
|
|
node_number= |
|
0 |
#Номертекущегоузла |
|
|
current=_node |
|
self.head |
#Начинаемобходсголовысписка |
|
|
previous=currnodent_node |
#Запоминаемпредыдущийузел |
|
|
||
#Идёмпоспискупока,недойдёмконца |
|
|
|
||
while current_node is not None: |
|
|
|||
#Еслинашлиузелснужныминдексом |
|
|
|
||
if index==node_number: |
|
|
|
||
#Предыдущийузелтеперьуказывнаузелет, |
следующийзаудаляемым |
|
|||
previous_node=current.next_node.next |
|
|
|||
#Отвязываемудаляемыйузел(длябезопасности) |
|
|
|||
current_node= |
.next |
None |
|
|
|
return |
|
|
|
|
|
#Переходимкследующемуузлу |
|
|
|
||
previous=currentnode _node |
|
|
|
||
current=_currentnode_node.next |
|
|
|
||
node_number+= |
|
1 |
|
|
|
def set_value_by_index(self, value, index): |
|
|
|||
#Номертекущегоузла(начинаемс0) |
|
|
|
||
node_number= |
|
0 |
|
|
|
#Начинаемобходсголовысписка |
|
|
|
||
current=_node |
|
self.head |
|
|
|
#Идёмпоспискупока,недойдёмконца |
|
||
while current_node |
is not None: |
|
|
#Еслинашлиузелснужныминдексом |
|
||
if node_number==index: |
|
||
#Заменяемданныевузленановоезначение |
|
||
current_node=value.data |
|
|
|
return |
|
|
|
#Переходимкследующемуузлу |
|
||
current=_currentnode_node.next |
|
||
node_number+= |
|
1 |
|
def get_value_by_index(self, index): |
|
||
#Номертекущегоузла(начинаемс0) |
|
||
node_number= |
0 |
|
|
#Начинаемобходсголовысписка |
|
|
|
current=_node |
self.head |
|
|
#Идёмпоспискупока,недойдёмконца |
|
||
while current_node |
is not None: |
|
|
#Еслинашлиузелснужныминдексом |
|
||
if index==node_number: |
|
||
#Возвращаемданныеизузла |
|
||
return current_node.data |
|
||
#Переходимкследующемуузлу |
|
||
current=_currentnode_node.next |
|
||
node_number+= |
|
1 |
|
#Еслииндексненайден(выходзаграницысписка), |
возвращаемNone |
||
return None |
|
|
|
Методы для получения размера
def get_length(self): |
|
||
#Переменнаядляподсчётаколичестваузлов |
|
||
length= |
0 |
|
|
#Начинаемобходсголовысписка |
|
||
current=_node |
self.head |
|
|
#Проходимповсемузламсписка |
|
||
while current_node is not None: |
|
||
length+= |
|
1 |
#Увеличиваемсчётчик |
current=_currentnode_node.next |
#Переходимкследующемуузлу |
||
#Возвращаемобщееколичествоузловсписке return length
Использование фиктивного начального узла
Для упрощения реализации односвязного списка может быть использован фиктивный первый узел. Голова списка всегда указывает на фиктивный узел. Данные этого узла игнорируются. Применение фиктивного узла позволяет уменьшить количество проверок при реализации. К недостаткам стоит отнести необходимость выделения памяти для хранения фиктивного узла.
Напишите программный код или сгенерируйте его с помощью искусственного интеллекта.
Чтобы изменить содержимое ячейки, дважды нажмите на нее (или выберите "Ввод")
Чтобы изменить содержимое ячейки, дважды нажмите на нее (или выберите "Ввод")
Чтобы изменить содержимое ячейки, дважды нажмите на нее (или выберите "Ввод")
Чтобы изменить содержимое ячейки, дважды нажмите на нее (или выберите "Ввод")
Чтобы изменить содержимое ячейки, дважды нажмите на нее (или выберите "Ввод")
