Проще простого™. Часть 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 февраля 200819:28 Заметил минут в юзабилити. На главной не показываются теги записей. Так что понять что пример на PHP можно только после прочтения некоторого количества кода или заглядывания в конец страницы. Было б лучше, раз уж «Проще простого™», указывать язык в начале статьи. Хотя наверное лучше указывать язык непосредственно для каждого фрагмента кода :)

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

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

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

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

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

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

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

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

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

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

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

    14 февраля 200811:19 > И именно хватало обычных очередей
    А массива не хватало?)
  • Дин

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

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

    10 марта 200822:36 Спс за теги.
  • ываыва

    24 февраля 200813:11 f
  • Mischka

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

    15 февраля 200819:37 Я считаю, что не только языка, но и теории в целом. Ведь так?
  • Mischka

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

    16 февраля 200812:52 Ага... Я сначала хотел на C++ написать примеры (всё равно пишу Web-сервер), но потом решил почему-то на PHP.
  • Mecha

    16 августа 200818:05

    FILO? Maybe LIFO?

  • Дин

    16 августа 200818:42

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

Я тоже знаю!

Вы можете тоже написать собственный комментарий. Если хотите к кому-то обратиться, используйте символ @, после которого не забудьте написать имя того, к кому обращаетесь. Не забывайте про существование XHTML-элементов, с помощью которых вы можете оформить ваш комментарий как вам угодно. И, да: ведите себя достойно, вы же не роботы, правда? Если вам интересно, можете подписаться на комментарии по RSS.