147
правок
Изменения
Очередь
,Новая страница: «'''О́чередь''' — структура данных с дисциплиной доступа к элементам «первый пришёл — пе…»
'''О́чередь''' — [[структура данных]] с дисциплиной доступа к элементам «первый пришёл — первый вышел» (FIFO, First In — First Out). Добавление элемента (принято обозначать словом enqueue — поставить в очередь) возможно лишь в конец очереди, выборка — только из начала очереди (что принято называть словом dequeue — убрать из очереди), при этом выбранный элемент из очереди удаляется.
== Способы реализации очереди ==
Существует несколько способов реализации очереди на языках программирования.
=== Массив ===
Первый способ представляет очередь в виде [[массив]]а и двух целочисленных [[переменная|переменных]] start и end.<br />
[[Файл:Queue1.gif]]<br />
Обычно <code>start</code> указывает на голову очереди, <code>end</code> — на элемент, который заполнится, когда в очередь войдёт новый элемент. При добавлении элемента в очередь в <code>q[end]</code> записывается новый элемент очереди, а <code>end</code> уменьшается на единицу. Если значение end становится меньше 1, то мы как бы циклически обходим массив и значение переменной становится равным n. Извлечение элемента из очереди производится аналогично: после извлечения элемента <code>q[start]</code> из очереди переменная <code>start</code> уменьшается на 1. С такими алгоритмами одна ячейка из <code>n</code> всегда будет незанятой (так как очередь с <code>n</code> элементами невозможно отличить от пустой), что компенсируется простотой алгоритмов.
Преимущества данного метода: возможна незначительная экономия памяти по сравнению со вторым способом; проще в разработке.
Недостатки: максимальное количество элементов в очереди ограничено размером массива. При его переполнении требуется перевыделение памяти и копирование всех элементов в новый массив.
=== Связный список ===
Второй способ основан на работе с динамической памятью. Очередь представляется в качестве [[линейный список|линейного списка]], в котором добавление/удаление элементов идет строго с соответствующих его концов.
Преимущества данного метода: размер очереди ограничен лишь объёмом памяти.
Недостатки: сложнее в разработке; требуется больше памяти; при работе с такой очередью память сильнее фрагментируется; работа с очередью несколько медленнее.
=== Реализация на двух стеках ===
Очередь может быть построена из двух [[стек]]ов <code>S1</code> и <code>S2</code> как показано ниже:
'''Процедура''' enqueue(''x''):
S1.push(''x'')
'''Процедура''' dequeue():
'''если''' S2 пуст:
'''если''' S1 пуст:
сообщить об ошибке: очередь пуста
'''пока''' S1 не пуст:
S2.push(S1.pop())
'''return''' S2.pop()
Такой способ реализации наиболее удобен в качестве основы для построения [[Персистентная структура данных|персистентной]] очереди.
== Очереди в различных языках программирования ==
Практически во всех развитых языках программирования реализованы очереди. В [[Common Language Infrastructure|CLI]] для этого предусмотрен класс System.Collections.Queue с методами Enqueue и Dequeue. В [[Стандартная библиотека шаблонов|STL]] также присутствует класс queue<>, определённый в заголовочном файле queue. В нём используется та же терминология (push и pop), что и в [[стек]]ах.
== Применение очередей ==
Очередь в программировании используется, как и в реальной жизни, когда нужно совершить какие-то действия в порядке их поступления, выполнив их последовательно. Примером может служить организация событий в Windows. Когда пользователь оказывает какое-то действие на приложение, то в приложении не вызывается соответствующая процедура (ведь в этот момент приложение может совершать другие действия), а ему присылается сообщение, содержащее информацию о совершенном действии, это сообщение ставится в очередь, и только когда будут обработаны сообщения, пришедшие ранее, приложение выполнит необходимое действие.
Клавиатурный буфер [[BIOS]]<!-- Вариант аббревиатуры "ВСУВВ" вообще нигде не встречается на Википедии --> организован в виде кольцевого массива, обычно длиной в 16 машинных слов, и двух указателей: на следующий элемент в нём и на первый незанятый элемент.
== См. также ==
* [[Структуры данных]]
* [[Коллекция (программирование)|Коллекция]]
* [[Массив]]
* [[Связный список|Список]]
* [[Стек]]
* [[Дэк]]
* [[Очередь с приоритетом]]
* [[Именованный канал]]
== Ссылки ==
== Способы реализации очереди ==
Существует несколько способов реализации очереди на языках программирования.
=== Массив ===
Первый способ представляет очередь в виде [[массив]]а и двух целочисленных [[переменная|переменных]] start и end.<br />
[[Файл:Queue1.gif]]<br />
Обычно <code>start</code> указывает на голову очереди, <code>end</code> — на элемент, который заполнится, когда в очередь войдёт новый элемент. При добавлении элемента в очередь в <code>q[end]</code> записывается новый элемент очереди, а <code>end</code> уменьшается на единицу. Если значение end становится меньше 1, то мы как бы циклически обходим массив и значение переменной становится равным n. Извлечение элемента из очереди производится аналогично: после извлечения элемента <code>q[start]</code> из очереди переменная <code>start</code> уменьшается на 1. С такими алгоритмами одна ячейка из <code>n</code> всегда будет незанятой (так как очередь с <code>n</code> элементами невозможно отличить от пустой), что компенсируется простотой алгоритмов.
Преимущества данного метода: возможна незначительная экономия памяти по сравнению со вторым способом; проще в разработке.
Недостатки: максимальное количество элементов в очереди ограничено размером массива. При его переполнении требуется перевыделение памяти и копирование всех элементов в новый массив.
=== Связный список ===
Второй способ основан на работе с динамической памятью. Очередь представляется в качестве [[линейный список|линейного списка]], в котором добавление/удаление элементов идет строго с соответствующих его концов.
Преимущества данного метода: размер очереди ограничен лишь объёмом памяти.
Недостатки: сложнее в разработке; требуется больше памяти; при работе с такой очередью память сильнее фрагментируется; работа с очередью несколько медленнее.
=== Реализация на двух стеках ===
Очередь может быть построена из двух [[стек]]ов <code>S1</code> и <code>S2</code> как показано ниже:
'''Процедура''' enqueue(''x''):
S1.push(''x'')
'''Процедура''' dequeue():
'''если''' S2 пуст:
'''если''' S1 пуст:
сообщить об ошибке: очередь пуста
'''пока''' S1 не пуст:
S2.push(S1.pop())
'''return''' S2.pop()
Такой способ реализации наиболее удобен в качестве основы для построения [[Персистентная структура данных|персистентной]] очереди.
== Очереди в различных языках программирования ==
Практически во всех развитых языках программирования реализованы очереди. В [[Common Language Infrastructure|CLI]] для этого предусмотрен класс System.Collections.Queue с методами Enqueue и Dequeue. В [[Стандартная библиотека шаблонов|STL]] также присутствует класс queue<>, определённый в заголовочном файле queue. В нём используется та же терминология (push и pop), что и в [[стек]]ах.
== Применение очередей ==
Очередь в программировании используется, как и в реальной жизни, когда нужно совершить какие-то действия в порядке их поступления, выполнив их последовательно. Примером может служить организация событий в Windows. Когда пользователь оказывает какое-то действие на приложение, то в приложении не вызывается соответствующая процедура (ведь в этот момент приложение может совершать другие действия), а ему присылается сообщение, содержащее информацию о совершенном действии, это сообщение ставится в очередь, и только когда будут обработаны сообщения, пришедшие ранее, приложение выполнит необходимое действие.
Клавиатурный буфер [[BIOS]]<!-- Вариант аббревиатуры "ВСУВВ" вообще нигде не встречается на Википедии --> организован в виде кольцевого массива, обычно длиной в 16 машинных слов, и двух указателей: на следующий элемент в нём и на первый незанятый элемент.
== См. также ==
* [[Структуры данных]]
* [[Коллекция (программирование)|Коллекция]]
* [[Массив]]
* [[Связный список|Список]]
* [[Стек]]
* [[Дэк]]
* [[Очередь с приоритетом]]
* [[Именованный канал]]
== Ссылки ==