Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лекции / Лекция_9_Структуры_данных_продолжение_ipynb_Colab (1)

.pdf
Скачиваний:
0
Добавлен:
28.06.2026
Размер:
1.8 Mб
Скачать

Оценка сложности операций

Операция

Сложность операции в худшем случае

Вставка элемента

Получение без удаления

Получение с удалением

Получение размера

Реализация на Python

Отсутствие массивов в Python Так как в Python отсутствует поддержка массивов, то реализация стека на их основе становится бессмысленной.

Очередь на основе двусвязного списка

Очередь это абстрактный тип данных, представляющий собой список элементов, организованных по принципу FIFO (англ. first in — first out, «первым пришёл первым вышел»).

Очередь динамическая структура данных.

Поддерживаемые операции:

Добавление элемента в конец очереди (enqueue) Удаление элемента из головы очереди (dequeue) Получение головного элемента без удаления (peek)

Получение размера очереди

Реализация очереди на основе двусвязного списка

Пожалуй одной из самых простых реализаций очереди является использование двусвязного списка. У него операции добавления элемента в начало списка и удаления элемента с конца списка обладают константной сложностью, что делает его использование довольно оптимальным. К недостаткам стоит отнести повышенный расход памяти на хранение ссылок на элементы списка.

Добавление значения в конец очереди

Получение значения с удалением с головы очереди

Получение значения без удаления с головы очереди

Получение размера очереди

Для получения размера очереди стоит объявить переменную с начальным значением 0. Начиная с начала очереди выполнять переход по ссылке к следующему узлу. На каждом переходе увеличивать значение этой переменной на 1. Закончить на tail.

Реализация на Python

Описание структуры узла и очереди

class Node:

def __init__(self, data=None, next=None, prev=None):

#Инициализузладанныеция: ссылка,наследующий

узелссылка, напредыдущийузел

self.data=data

 

 

self.next=next

 

 

self.prev=prev

 

 

def __str__(self):

 

 

#Припреобразованиистрокувозвращаемданные

узла(опечаткаdate->data):

return str(self.data)

 

class Queue:

 

 

 

def __init__(self):

 

#Создаёмфиктивныеузлыheadиtail

 

self.head=Node

()

#Головачереди(фиктивныйузел)

self.tail=Node

()

#Хвосточереди(фиктивныйузел)

#Связываемheadиtail:headуказываетнаtail,

tailуказываетнаhead

self.head=.next

self.tail

 

self.tail=.prev

self.head

 

#Длинаочереди(количествореальныхузлов)

 

self.length=

 

0

 

Методы добавления в конец очереди

def enqueue(self, value):

 

#Создаёмновыйузел:

 

 

 

#-data=value

 

 

 

#-next=self.head(текущий.nextпервыйреальный

узел)

#-prev=self.(headфиктивнаяголова)

 

add_node=Node(value,

 

self.head.next, self.head)

#Текущийпервыйреальныйузелтеперьдолжен

указыватьнановыйузелкакнапредыдущий

self.head.next=add.prevnode

 

#Головатеперьуказываетнановыйузелкакна

первыйреальный

self.head=.addnextnode

 

 

#Увеличиваемдлинуочереди

 

 

self.length+=

1

 

 

Метод получения с удалением

def dequeue(self):

#Еслиочередьпустаничего, невозвращаем(или if self.is_empty():

return None

#Узелкоторый, нужноудалить(последнийреальный remove=_node self.tail.prev

#Хвосттеперьуказываетнапредыдущийперед self.tail=.removeprev_node.prev

#Новыйпоследнийреальныйузелтеперьуказывает remove_node=.prev.next self.tail

#Сохраняемданныеизудаляемогоузла return=removevalue_node.data

#Отвязывудаляемыйузел(длябезопасности) remove_node= .next None remove_node= .prev None

#Уменьшаемдлинуочереди self.length-= 1

#Возвращаемданныеудалённогоэлемента return return_value

Методы получения без удаления

def peek(self):

#Еслиочередьпустаничего, невозвращаем(или if self.is_empty():

return None

#Получаемпоследнийреальныйузел(перед remove=_node self.tail.prev

#Возвращаемданныеизузлабезегоудаления return remove_node.data

можновернутьNone)

узелперед, фиктивнымtail)

удаляемымузел

нахвосткакнаследующий

можновернутьNone)

фиктивнымtail)

Методы получения длины

def get_length(self):

 

 

#Начинаспервогомреальногоузла(после

фиктивногоhead)

current=_node

self.head.next

 

#Счётчикдлиныочереди

 

 

length=

0

 

 

 

#Проходимповсемреальнымузлампока,недойдём

дофиктивногоtail

while current!=node

self.tail:

 

length+=

 

1

 

#Увеличиваемсчётчик

current=currentnode _node.next

#Переходимкследующемуузлу

#Возвращаемколичествореальныхузловочереди return length

Очередь на основе массива

Реализация очереди на основе массива

Для реализации очереди можно использовать одномерные массивы. Такой подход позволит значительно снизить затраты памяти на хранение по сравнению с очередью на основе двусвязного списка (не нужно хранить множество ссылок на соседние элементы). Идея и реализация также довольно простые. С помощью двух переменных хранят индексы, указывающие на начало и конец очереди. Важной особенностью подобных индексов является их цикличность. Это означает, что дойдя до конца последовательности, они переходят в её начало.

Добавление значения в конец очереди (tail + 1 ≠ head)

Добавление значения в конец очереди (tail + 1 = head)

Получение значения с удалением с головы очереди

Получение значения без удаления с головы очереди

Уменьшение размера очереди

В большинстве случаев очередь на основе массива только увеличивает свой размер. Автоматического уменьшения не предусматривают. Для уменьшения размера используют функцию, вызов которой осуществляется по желанию разработчика.

Получение размера очереди

Для получения размера очереди стоит объявить переменную с начальным значением 0. Начиная с начала очереди добавляем к значению head и этой переменной единицу, до тех пор пока head не станет равно tail. Вернуть значение переменной.

Реализация на Python

Так как в Python отсутствует достаточная поддержка массивов, то реализация очереди на их основе не рассматривается.

Напишите программный код или сгенерируйте его с помощью искусственного интеллекта.

Чтобы изменить содержимое ячейки, дважды нажмите на нее (или выберите "Ввод")

Чтобы изменить содержимое ячейки, дважды нажмите на нее (или выберите "Ввод")

Чтобы изменить содержимое ячейки, дважды нажмите на нее (или выберите "Ввод")

Чтобы изменить содержимое ячейки, дважды нажмите на нее (или выберите "Ввод")

Чтобы изменить содержимое ячейки, дважды нажмите на нее (или выберите "Ввод")

Чтобы изменить содержимое ячейки, дважды нажмите на нее (или выберите "Ввод")

Чтобы изменить содержимое ячейки, дважды нажмите на нее (или выберите "Ввод")

Чтобы изменить содержимое ячейки, дважды нажмите на нее (или выберите "Ввод")