Очередь — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
м
Строка 1: Строка 1:
 
== Определение ==
 
== Определение ==
'''Очередь''' (''Queue'')  — это динамическое множество, добавление и удаление элементов в котором происходит путём операций ''Push'' и ''Pop'' соответственно. Притом первым из очереди удаляется элемент, который был помещен туда первым, то есть в очереди реализуется стратегия «первым вошел — первым вышел» (first-in, first-out — FIFO).
+
[[Файл: Fifo_new.png|thumb|right|150px|Очердь]]
 +
'''Очередь''' (''Queue'')  — это динамическое множество, добавление и удаление элементов в котором происходит путём операций ''Push'' и ''Pop'' соответственно. Притом первым из очереди удаляется элемент, который был помещен туда первым, то есть в очереди реализуется стратегия «первым вошел — первым вышел» (''first-in, first-out — FIFO''). Очередь подобна, например, живой очередь в магазине за хлебом. У нее имеется '''голова''' (''head'') и '''хвост''' (''tail''). Когда элемент ставится в очередь, он занимает место в её хвосте, точно так же, как человек занимает очередь последним, чтобы купить хлеб. Из очереди всегда выводится элемент, который находится в её головной части аналогично тому, как человек, который ждал дольше всех, расплачивается за хлеб.
  
 +
== Реализация на массиве ==
 +
Операция вставки нового элемента называется <tex>push</tex> (запись в очередь), а операция удаления - <tex>pop</tex> (снятие с очереди), <tex>empty</tex> - проверка очереди на наличие в ней элементов. Очередь, способная вместить не более <tex>n</tex> элементов, можно реализовать с помощью массива <tex>elements[1..n]</tex>.
  
== Способы реализации очереди ==
+
Очередь будет обладать следующими полями:
 +
:<tex>head</tex> (голова очереди)
 +
:<tex>tail</tex> (хвост очереди)
 +
:<tex>size</tex> (размер очереди)
  
Существует несколько способов реализации очереди на языках программирования.
+
=== push ===
 
+
push(x)
[[Файл: Fifo.png | 300 px]]
+
    elements[tail] = x
 
+
    tail = (tail + 1) % elements.length
=== Массив ===
+
    size++
 
+
=== pop ===
Первый способ представляет очередь в виде массива m[] размером n и двух целочисленных переменных (указателей) start и end.<br />
+
  pop()
 
+
    if (!empty())  
Обычно start указывает на голову очереди, end — на элемент, который заполнится, когда в очередь войдёт новый элемент. При добавлении элемента в очередь в m[end] записывается новый элемент очереди, а end увеличивается на единицу. Если значение end становится равным n, то мы как бы циклически обходим массив и значение переменной становится равным 1. Извлечение элемента из очереди производится аналогично: после извлечения элемента m[start] из очереди переменная start увеличивается на 1, т.е как с переменной end. С такими алгоритмами одна ячейка из n всегда будет незанятой (так как очередь с n элементами невозможно отличить от пустой), что компенсируется простотой алгоритмов.
+
        then x = elements[head]
 
+
            head = (head + 1) % elements.length
Преимущества данного метода: возможна незначительная экономия памяти по сравнению со вторым способом; проще в разработке.
+
             size--
 
+
             return x
Недостатки: максимальное количество элементов в очереди ограничено размером массива. При его переполнении требуется перевыделение памяти и копирование всех элементов в новый массив.  
+
=== empty ===
 
+
empty()
=== Связный список ===
+
    return size == 0
Второй способ основан на работе с динамической памятью. Очередь представляется в качестве линейного списка, в котором добавление/удаление элементов идет строго с соответствующих его концов.
+
Каждая операция выполняется в течение времени <tex>O(1)</tex>.
 
 
Преимущества данного метода: размер очереди ограничен лишь объёмом памяти.
 
 
 
Недостатки: сложнее в разработке; требуется больше памяти; при работе с такой очередью память сильнее фрагментируется; работа с очередью несколько медленнее.
 
 
 
=== Реализация на двух стеках ===
 
Очередь может быть построена из двух [[стек]]ов <code>S1</code> и <code>S2</code> как показано ниже:
 
 
 
[[Файл: queue.png | 400 px]]
 
 
 
  '''Процедура''' enqueue(''x''):
 
    S1.push(''x'')
 
 
'''Процедура''' dequeue():
 
    '''если''' S2 пуст:
 
        '''если''' S1 пуст:
 
             сообщить об ошибке: очередь пуста
 
 
        '''пока''' S1 не пуст:
 
             S2.push(S1.pop())
 
 
    '''return''' S2.pop()
 
 
 
 
 
 
 
== Очереди в различных языках программирования ==
 
Практически во всех развитых языках программирования реализованы очереди. В CLI для этого предусмотрен класс System.Collections.Queue с методами Enqueue и Dequeue. В STL присутствует класс queue<>, определённый в заголовочном файле queue. В нём используется та же терминология (push и pop), что и в [[стек]]ах.
 
 
 
== Применение очередей ==
 
Очередь в программировании используется, как и в реальной жизни, когда нужно совершить какие-то действия в порядке их поступления, выполнив их последовательно. Примером может служить организация событий в Windows. Когда пользователь оказывает какое-то действие на приложение, то в приложении не вызывается соответствующая процедура (ведь в этот момент приложение может совершать другие действия), а ему присылается сообщение, содержащее информацию о совершенном действии, это сообщение ставится в очередь, и только когда будут обработаны сообщения, пришедшие ранее, приложение выполнит необходимое действие.
 
 
 
Клавиатурный буфер BIOS организован в виде кольцевого массива, обычно длиной в 16 машинных слов, и двух указателей: на следующий элемент в нём и на первый незанятый элемент.(реализация очереди на массиве)
 
  
 
== См. также ==
 
== См. также ==

Версия 21:06, 12 марта 2012

Определение

Очердь

Очередь (Queue)  — это динамическое множество, добавление и удаление элементов в котором происходит путём операций Push и Pop соответственно. Притом первым из очереди удаляется элемент, который был помещен туда первым, то есть в очереди реализуется стратегия «первым вошел — первым вышел» (first-in, first-out — FIFO). Очередь подобна, например, живой очередь в магазине за хлебом. У нее имеется голова (head) и хвост (tail). Когда элемент ставится в очередь, он занимает место в её хвосте, точно так же, как человек занимает очередь последним, чтобы купить хлеб. Из очереди всегда выводится элемент, который находится в её головной части аналогично тому, как человек, который ждал дольше всех, расплачивается за хлеб.

Реализация на массиве

Операция вставки нового элемента называется [math]push[/math] (запись в очередь), а операция удаления - [math]pop[/math] (снятие с очереди), [math]empty[/math] - проверка очереди на наличие в ней элементов. Очередь, способная вместить не более [math]n[/math] элементов, можно реализовать с помощью массива [math]elements[1..n][/math].

Очередь будет обладать следующими полями:

[math]head[/math] (голова очереди)
[math]tail[/math] (хвост очереди)
[math]size[/math] (размер очереди)

push

push(x)
   elements[tail] = x
   tail = (tail + 1) % elements.length
   size++

pop

pop()
   if (!empty()) 
       then x = elements[head]
            head = (head + 1) % elements.length
            size--
            return x

empty

empty()
   return size == 0

Каждая операция выполняется в течение времени [math]O(1)[/math].

См. также


Ссылки

http://ru.wikipedia.org/wiki/Очередь_(программирование)