From 061cd2a81c7af606d964b2511e3b1f49e18e5123 Mon Sep 17 00:00:00 2001 From: egorzhurov Date: Sat, 11 May 2024 22:08:55 +0300 Subject: [PATCH] Move 39 article to markdown format --- .../java-core/039/Linked lists and queues.md | 147 ++++++++++++++++++ lessons/java-core/039/doublyLinkedList.png | Bin 0 -> 6309 bytes lessons/java-core/039/singlyLinkedList.png | Bin 0 -> 4527 bytes 3 files changed, 147 insertions(+) create mode 100644 lessons/java-core/039/Linked lists and queues.md create mode 100644 lessons/java-core/039/doublyLinkedList.png create mode 100644 lessons/java-core/039/singlyLinkedList.png diff --git a/lessons/java-core/039/Linked lists and queues.md b/lessons/java-core/039/Linked lists and queues.md new file mode 100644 index 0000000..efefb0a --- /dev/null +++ b/lessons/java-core/039/Linked lists and queues.md @@ -0,0 +1,147 @@ +# Queue и вариации на тему. Часть I. Структуры данных + +Следующий тип коллекций, с которым мы познакомимся – **Queue – очередь**. + +В рамках этого урока мы разберем несколько структур данных, которые применяются в коллекциях данного типа. В следующей +части этого урока – познакомимся с имплементациями этих структур в рамках Collections Framework. + +В классическом представлении, Queue – структура данных, строящаяся на принципе **FIFO – first-in, first-out** (первый +вошел – первый вышел). В целом, принцип достаточно очевиден и часто употребим в реальной жизни (куда чаще, чем также +знакомый нам LIFO). + +Забавно, но программная реализация FIFO сложнее, чем LIFO:) + +Однако в Java под коллекциями типа Queue понимаются не только очереди в классическом представлении, а целый набор +различных структур данных от связных списков (в разных вариациях) до стеков и, непосредственно, очередей. И не все +очереди в итоге следуют FIFO. В общем, все не так просто, как хотелось бы. + +Итак, постараемся разобраться со структурами данных. + +## Структуры данных. Связный список. + +**Связный список** – одна из классических структур данных, минимальной самостоятельной частью которой является **узел +(Node, нода)**, хранящий элемент(полезную нагрузку, в нашем случае - объект какого-то класса) и ссылку (ссылки) на +следующий и/или предыдущий элемент(-ы). + +Из наиболее классических реализаций можно выделить **односвязный список** (есть ссылка на узел-вершину, каждый узел +хранит элемент и ссылку на следующий элемент). В ссылке на следующий узел у последнего узла в списке будет `null`: + +![img.png](singlyLinkedList.png) + +С таким списком мы уже знакомы из практики к [уроку 28](https://telegra.ph/Generics-CHast-I-12-12). Там произошла +некоторая путаница в названиях, но все же. + +Таким образом, односвязный список работает по принципу LIFO. Упоминаемый в практике выше **стек** – частный случай +односвязного списка. Их разница в том, что при получении элемента стека – элемент удаляется из структуры данных. В +контексте односвязного списка удаление элемента не регламентировано – оно может производиться или не производиться, в +зависимости от потребностей конкретной реализации. + +На этом этапе мы можем положить в копилку 2 новые структуры данных: односвязный список и стек. + +## Двусвязный список + +Двусвязный список немногим сложнее односвязного, но гораздо более функционален. + +Двусвязный список представляет собой ссылки на первый и (опционально) последний узлы. Каждый узел хранит элемент, а +также ссылки на следующий и предыдущий элементы: + +![img.png](doublyLinkedList.png) + +Поле ссылки на предыдущий элемент у первого узла списка содержит `null`. Также и поле ссылки на следующий элемент у +последнего узла списка будет `null`. + +Двусвязный список может работать как по принципу FIFO, так и по принципу LIFO. + +Так, как стек является частным случаем односвязного списка, **двусторонняя (двусвязная) очередь (deque - double ended +queue, дек)** является частным случаем двусвязного списка. + +Двусторонняя очередь – структура данных, в которой добавление и удаление элементов возможно как с начала, так и с конца. +Пройти же вглубь очереди, не удаляя элементы, нельзя (так же, как и в стеке). + +На этом этапе в копилку структур данных отправляются еще две: двусвязный список и двусторонняя очередь. + +## Очередь + +Возвращаясь к классической очереди – queue – все немного сложнее с точки зрения реализации. + +Если стек реализовывать удобно – наличия вершины и ссылки на следующий элемент достаточно, то в случае с очередью +необходимы: + +- ссылка на начало очереди, чтобы «доставать» (эту функцию называют в очередях и стеках _pop_) элементы; +- на конец очереди, чтобы элементы «добавлять» (_push_); +- ссылка на следующий узел у каждого из узлов, чтобы добавлять новые элементы и при этом иметь актуальную ссылку на + конец (хвост) очереди; +- ссылка на предыдущий узел у каждого из узлов, чтобы при выходе (pop) первого элемента получать ссылку на новое начало + очереди. + +В итоге получается, что для реализации односвязной очереди тоже нужен двусвязный список. + +В общем-то, так и есть: одна из классических реализаций очереди основана на двусвязном списке. Альтернативные +реализации – на базе массива (на его основе иногда (на самом деле, часто) реализуют и стек), а также в виде двух +стеков (советую погуглить, выглядит достаточно оригинально). + +## Вместо итога + +Важно понимать, что некоторые структуры данных (в нашем случае – разные виды списков) регулируют лишь способ хранения +данных, некоторые же (стек, очереди) – описывают допустимые способы обработки данных. + +При этом вторая группа структур более высокоуровневая и больше похожа на интерфейсы – стек/очереди описывают, что +структура умеет (должна уметь) делать, но не говорят о том, как это сделать. Иными словами, описывают контракт +взаимодействия. + +В то время как первая группа (списки) – не ограничивает в функциональности, предоставляя лишь инфраструктуру хранения +данных и связь между ними (ссылки на следующий/предыдущий элемент). + +Также очень важно понимать, что рассмотренные выше структуры данных – не единственные. И даже не единственные в своем +классе. Те же списки имеют массу реализаций, кроме двух рассмотренных. Например, кольцевые списки, развернутые списки, +списки с пропусками и пр. + +Тема структур данных глубока, многогранна и интересна. Мы ее касаемся лишь минимально, на том уровне, который необходим +для понимания инструментов, которые изучаем на данный момент. Но даже в отношении рассмотренных структур данных я +рекомендую закрепить их понимание информацией со сторонних ресурсов. В обязательном порядке – посмотреть, какую +функциональность должны предоставлять изученные структуры (особенно актуально для стека и очередей). Чем лучше вы +разберетесь с этим сейчас, тем легче будет в дальнейшем. + +В следующем уроке мы рассмотрим реализации изученных структур в Java-коллекциях. + +#### С теорией на сегодня все! + +![img.png](../../../commonmedia/defaultFooter.jpg) + +Переходим к практике: + +## Задача 1 (*): + +Реализуйте односвязный список (можно использовать +[реализацию](https://github.com/KFalcon2022/practical-tasks/blob/master/src/com/walking/lesson28_generics1/task4/structure/Stack.java) +в рамках урока 28). + +Реализуйте метод, разворачивающий односвязный список (первый элемент должен стать последним, второй – предпоследним и +т.д.). + +Также реализуйте метод, удаляющий все узлы, хэшкод элемента которых - четный. + +## Задача 2: + +Реализуйте структуру данных стек. Используйте односвязный список из Задачи 1. При этом изменять сам класс, реализующий +односвязный список, недопустимо. + +## Задача 3: + +Реализуйте двусвязный список. + +Реализуйте метод, разворачивающий список. + +Также реализуйте метод, удаляющий все узлы, хэшкод элемента которых - четный. + +## Задача 4: + +Реализуйте одностороннюю очередь на базе двусвязного списка из Задачи 3. + +> Если что-то непонятно или не получается – welcome в комменты к посту или в лс:) +> +> Канал: https://t.me/ViamSupervadetVadens +> +> Мой тг: https://t.me/ironicMotherfucker +> +> **Дорогу осилит идущий!** \ No newline at end of file diff --git a/lessons/java-core/039/doublyLinkedList.png b/lessons/java-core/039/doublyLinkedList.png new file mode 100644 index 0000000000000000000000000000000000000000..ec020650ed658f357491d1f8897b69cc8bd7a218 GIT binary patch literal 6309 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 literal 0 HcmV?d00001 diff --git a/lessons/java-core/039/singlyLinkedList.png b/lessons/java-core/039/singlyLinkedList.png new file mode 100644 index 0000000000000000000000000000000000000000..921d28636631787e00edafc083de1623fc6d5db6 GIT binary patch literal 4527 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