Проще простого™. Часть 1.

13 февраля 2008 года, 11:39

Цикл «Проще простого™» поможет познать очень простые вещи.

Сегодня мы рассмотрим два простых контейнера — это очередь (queue) и стек (stack). Так как данные простые вещи действительно являются простыми, то они не нуждаются в дальнейшем разъяснении: все комментарии приведены в самом коде. Примеры написаны на PHP.

Очередь

/* * Очередь очень похожа на стек, но также похожа и на реальную очередь. * Реализуется она по принципу FIFO. * FIFO значит, что элемент, пришедший первым, первым и покинет контейнер. * Данный класс является простейшей реализацией очереди. */ class Queue { //Элементы очереди private $Elements; //Конструктор public function __construct() { $this->Elements = Array(); } //Добавить элемент в очередь public function Insert($element) { array_push($this->Elements, $element); } //Удалить последний элемент из очереди public function Remove() { if ($this->GetSize() != 0) return array_shift($this->Elements); } //Запросить первый элемент очереди (пришешдий последним) public function RetreiveFirst() { return $this->Elements[0]; } //Запросить последний элемент очереди (пришешдий первым) public function RetreiveLast() { return end($this->Elements); } //Получение количества элементов в очереди public function GetSize() { return count($this->Elements); } }

Попробуем!

//Создаём очередь $MyQueue = new Queue(); //Добавляем элементы в очередь $MyQueue->Insert(5); //В очереди: 5 $MyQueue->Insert(12); //В очереди: 5 12 $MyQueue->Insert(20); //В очереди: 5 12 20 //Получаем первый и последний элементы echo $MyQueue->RetreiveFirst(); //Результат: 5 echo $MyQueue->RetreiveLast(); //Результат: 20 //Удаляем элементы из очереди $MyQueue->Remove(); //В очереди: 12 20 $MyQueue->Remove(); //В очереди: 20

Стек

/* * Стек реализуется по принципу FILO. * FILO значит, что элемент, который приходит первым, покидает контейнер последним. * Из стека мы можем получить только вершину, остальные части стека мы видеть не можем. * Данный класс является самой простой реализацией стека на PHP. */ class Stack { //Элементы стека private $Elements; //Конструктор public function __construct() { $this->Elements = Array(); } //Добавление элемента в стек public function Push($element) { array_push($this->Elements, $element); } //Запрос верхушки стека //Не удаляет верхний элемент public function RetreiveTop() { return end($this->Elements); } //Запрос верхушки стека и удаление его public function Pop() { if ($this->GetSize() != 0) return array_pop($this->Elements); } //Получение количества элементов в стеке public function GetSize() { return count($this->Elements); } }

Проверяем стек

//Создаём стек (верхушка стека сейчас не существует [равна нулю]) $MyStack = new Stack(); //Добавляем элементы в стек $MyStack->Push(5); //В стеке: 5 [верхушка] $MyStack->Push(12); //В стеке: 12 [верхушка], 5 $MyStack->Push(20); //В стеке: 20 [верхушка], 12, 5 //Получаем верхушку (последний добавленный элемент, но не удаляем) echo $MyStack->RetreiveTop(); //Результат: 20 //Получаем верхушку, удаляя её из стека (поднимая все предыдущие элементы) $MyStack->Pop(); //В стеке: 12 [верхушка], 5 $MyStack->Pop(); //В стеке: 5 [верхушка] $MyStack->Pop(); //В стеке: стек пуст

На сегодня всё. Продолжения обязательно будут. Всем удачного дня!

Мнения (14)

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

  • SnS

    13 февраля 2008 г.19:28

    Заметил минут в юзабилити. На главной не показываются теги записей. Так что понять что пример на PHP можно только после прочтения некоторого количества кода или заглядывания в конец страницы. Было б лучше, раз уж «Проще простого™», указывать язык в начале статьи. Хотя наверное лучше указывать язык непосредственно для каждого фрагмента кода :)

    А по делу могу сказать, что слабо представляю себе применение очередей и стеков в PHP, зато они часто используются в JavaScript. Не стоило бы пример писать на нём? :)

  • Дин автор

    13 февраля 2008 г.19:35

    Специально теги убрал с главной страницы. Мне кажется, что это служебная информация и к главной странице она слабо привязывается какой-либо стороной.

    Насчёт указания языка — я подумаю, как сделать наиболее удобно.

    Множество примеров можно привести: обработка XML (парсинг RAW-XML-документа) — стек, выполнение отложенный заданий базы данных — стек или очередь, выполнение заданий в TaskManager'е (специальные бизнес Web-приложения) — очередь (обычно так, либо очередь с приоритетами, в усложнённых ситуациях). На самом деле, это всё очень удобный список. Можно расширить данные классы, как я уже сказал, и получить мощное средство манипулирования данными.

    А насчёт стеков и очередей в JavaScript — вот ни разу не использовал, хоть пытайте меня в газовой камере.

  • Sannis

    13 февраля 2008 г.21:23

    Хм. С XML я соглашусь. А вот насчёт БД и тасков не знаю.

    Пока что не встречал задач, где порядок выполнения таких запросов имел значение => можно обойтись массивом. А если порядок важен, то имхо очередью/стеком не обойтись, часть запросов же будет взаимосвязанна, а часть нет, значит можно использовать массив для вторых и спецлогику для первых...

    Задачи как правило тоже бывают громоздкими, и не выполняются за время работы одного скрипта(непонятно пишу, но думаю поймёте меня:), а тогда зачем вообще их структурировать, если можно выбрать только ту, которую нужно выполнять сейчас?

    Хотя да, с явоскриптом я похоже загнул, наверное слишком много кода всяких библиотек пропустил через себя в последнюю неделю %]

  • Дин автор

    14 февраля 2008 г.07:10

    Я встречал, неоднократно. И именно хватало обычных очередей: остальные специальные дополнения были уже излишними и нагрузочными.

    Ну, например, в распределённом отложенном менеджере запросов MySQL можно реализовать стек запросов, чтобы в последствии их исполнять централизованно.

  • Sannis

    14 февраля 2008 г.11:19

    > И именно хватало обычных очередей
    А массива не хватало?)

  • Дин автор

    14 февраля 2008 г.11:27

    Ну тут уже греет душу удобная абстракция над массивом и в любое время я могу изменить реализацию абстракции (стек, очередь, список) и эти изменения не коснутся того, как мы используем её в наших приложениях.

    Другой плюс (для меня) есть оперирование со вполне видимыми и именованными объектами не в ущерб производительности.

  • Sannis

    10 марта 2008 г.22:36

    Спс за теги.

  • ываыва

    24 февраля 2008 г.13:11

    f

  • Mischka

    15 февраля 2008 г.08:59

    Очередь и стек (на любом языке программирования) — всегда являлись отличным методическим пособием для начинающих углубленное изучение языка. Так что это отличный подарок студенту, который хочет чему-то научиться, а не просто сдать сессию.

  • Дин автор

    15 февраля 2008 г.19:37

    Я считаю, что не только языка, но и теории в целом. Ведь так?

  • Mischka

    16 февраля 2008 г.07:28

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

  • Дин автор

    16 февраля 2008 г.12:52

    Ага... Я сначала хотел на C++ написать примеры (всё равно пишу Web-сервер), но потом решил почему-то на PHP.

  • Mecha

    16 августа 2008 г.18:05

    FILO? Maybe LIFO?

  • Дин автор

    16 августа 2008 г.18:42

    @Mecha, одно и тоже. :-)

Я тоже знаю!

Для обращения к человеку используйте символ @, после которого следует имя того, к кому обращаетесь (пробелы заменяются на знак подчёркивания). Если вам интересно, можете подписаться на комментарии по RSS или по эл. почте. Ведите себя достойно, вы же не роботы, правда?

Вы можете использовать следующие XHTML-элементы в разметке комментария: strong, em, span[class=crossline], a[href=uri], code[type=язык], blockquote, ul и ol. В качестве языка кода может быть указан, например, javascript или css.