Kolejka — struktura danych (FIFO): definicja, operacje i priorytetowa

Kolejka FIFO — definicja, operacje (enqueue, dequeue, peek) i kolejka priorytetowa. Przykłady, zastosowania i praktyczne wyjaśnienie dla programistów i studentów.

Autor: Leandro Alegsa

W informatyce kolejka jest strukturą danych, używaną do przechowywania elementów, zanim zostaną one przetworzone. Ogólnie rzecz biorąc, istnieją następujące operacje:

  • Enqueue: dodaj element na koniec kolejki
  • Dequeue: usuń element z przodu kolejki
  • Opcjonalnie może istnieć operacja przeglądania elementu z przodu kolejki, bez jego usuwania.

Pozycje, które znajdują się pomiędzy pierwszym a ostatnim elementem kolejki nie są bezpośrednio dostępne.

Istnieje pewna specjalizacja, zwana kolejką priorytetową: W kolejce priorytetowej każdy element posiada również wagę, która określa pozycję elementu w kolejce.

Definicja i własności

Kolejka to abstrakcyjna struktura danych działająca zgodnie z zasadą FIFO (first-in, first-out) — elementy są usuwane w tej samej kolejności, w jakiej zostały dodane. Typowe operacje to:

  • enqueue (push, offer) — wstawienie elementu na koniec kolejki;
  • dequeue (pop, poll) — usunięcie i zwrócenie elementu z przodu kolejki;
  • peek (front, view) — odczyt elementu z przodu bez usuwania;
  • isEmpty — sprawdzenie, czy kolejka jest pusta;
  • size — zwrócenie liczby elementów w kolejce.

Implementacje

Kolejki można zaimplementować na kilka sposobów, różniących się złożonością operacji i wykorzystaniem pamięci:

  • Tablica cykliczna (circular buffer) — stała pamięć, dwa wskaźniki (head/tail). Operacje enqueue i dequeue w czasie O(1). Wymaga obsługi przepełnienia (overflow) lub mechanizmu rozszerzania.
  • Lista jednokierunkowa z wskaźnikami na początek i koniec — każdy enqueue dodaje element na końcu (O(1)), dequeue usuwa z początku (O(1)). Dynamiczne zarządzanie pamięcią, brak kosztownych przesunięć.
  • Deque (double-ended queue) — umożliwia operacje na obu końcach; może działać jako stos lub kolejka.
  • Kolejka priorytetowa — zwykle implementowana jako kopiec (binary heap) lub inne struktury (Fibonacci heap, drzewo Binomialne). Operacje insert i extract mają złożoności zależne od konkretnej implementacji (np. O(log n) dla binary heap).

Złożoność czasowa i złożoność pamięciowa

  • Standardowe operacje enqueue, dequeue i peek w dobrze zaimplementowanej kolejce (tablica cykliczna lub lista) mają złożoność O(1) czasu.
  • Kolejka priorytetowa (binary heap) oferuje zwykle O(log n) dla wstawiania i usuwania elementu o najwyższym priorytecie, a O(1) dla odczytu elementu najwyższego priorytetu (peek).
  • Pamięć: struktury dynamiczne wykorzystują pamięć proporcjonalną do liczby przechowywanych elementów O(n). Tablica o stałym rozmiarze zużywa z góry przydzieloną pamięć.

Warianty i rozszerzenia

  • Bounded queue — kolejka o ograniczonej pojemności; przy próbie wstawienia, gdy jest pełna, operacja może się nie powieść lub zablokować (w środowiskach wielowątkowych).
  • Unbounded queue — dynamicznie rozszerzana; ryzyko wyczerpania pamięci przy dużej liczbie elementów.
  • Blocking queue — w wielowątkowych systemach, operacje enqueue/dequeue mogą blokować wątek do czasu dostępności miejsca lub elementu (przykłady: Java BlockingQueue).
  • Lock-free / wait-free queues — implementacje bez blokad, przydatne w programowaniu współbieżnym dla zwiększenia wydajności i unikania zakleszczeń.
  • Stabilność priorytetów — w niektórych implementacjach kolejki priorytetowej elementy o tym samym priorytecie mogą zachowywać kolejność FIFO (stabilna kolejka priorytetowa).

Zastosowania

  • Algorytm BFS (przeszukiwanie wszerz) w grafach i drzewach.
  • Bufory i kolejki zadań w systemach operacyjnych (planowanie procesów, kolejki drukarki).
  • Komunikacja między procesami/wątkami — model producent-konsument.
  • Symulacje zdarzeń dyskretnych, gdzie zdarzenia są obsługiwane w kolejności zgłoszeń lub według priorytetu.
  • Obsługa żądań sieciowych i kolejkowanie zapytań w serwerach.

Błędy i przypadki brzegowe

  • Underflow — próba usunięcia elementu z pustej kolejki powinna być obsłużona (zwrot wartości specjalnej, wyjątek lub wartość null w zależności od API).
  • Overflow — dla kolejki ograniczonej należy zdefiniować zachowanie przy przepełnieniu (odrzucenie nowego elementu, blokowanie, rozszerzenie tablicy itp.).
  • Zarządzanie pamięcią i wydajnością w aplikacjach o dużym obciążeniu — konieczne monitorowanie i ew. ograniczanie długości kolejki.

Praktyczne wskazówki

  • W prostych zastosowaniach, gdy znamy maksymalny rozmiar, tablica cykliczna daje najlepszą wydajność i niską reżię pamięciową.
  • W aplikacjach współbieżnych używaj sprawdzonych struktur (np. implementacji z biblioteki standardowej języka), które zapewniają poprawność i wydajność.
  • Dla zadań wymagających priorytetowego przetwarzania wybierz strukturę priorytetową (kopiec), a jeśli ważna jest zachowana kolejność elementów o równym priorytecie — wybierz stabilną implementację.

Podsumowując, kolejka to prosta, lecz bardzo użyteczna struktura danych o szerokim zastosowaniu w informatyce. Wybór konkretnej implementacji powinien zależeć od wymagań dotyczących pamięci, czasu operacji oraz współbieżności.

A kolejkaZoom
A kolejka



Przeszukaj encyklopedię
AlegsaOnline.com - 2020 / 2025 - License CC3