Приоритетна опашка - първа част

Приоритетна опашка е АТД за съхраняване на съвкупност от елементи с приоритети, която поддържа вмъкване на произволен елемент, като премахването на елементи става по приоритет, т.е. елементът с първи приоритет може да бъде отстранен по всяко време.
Примери:
Приоритетът обикновено е числова стойност - най-малката стойност означава най-висок приоритет.

Ключове, приоритети и релации на пълна наредба

Ще дефинираме ключ като обект, прикачен към елемент и специфична негова характеристика и които може да бъде използван за идентификация, ранг, или тегло на този елемент.

Сравняване на ключове и пълна наредба

Да предположим, че даден полет е изцяло запълнен един час преди началото на пътуването. Поради възможността за отказване (анулиране), авиокомпанията поддържа приоритетната опашка на чакащите за място пътници. Приоритетът на всеки пътник се определя от стойността на билета, често-пътуващ статут (frequent-flyer status), както от и времето, когато пътникът е поставен в приоритетната опашка. Когато пътник се регистрира като чакащ за място, свързаният с пътника обект се добавя в приоритетната опашка с операция insertItem. Малко преди излитането на самолета, ако станат достъпни места (например, поради отказване в последната минута), авиокомпанията многократно премахва от приоритетната опашка чакащ за място пътник с първи приоритет, като се използва комбинация от minElement() и removeMin() операции и качва този пътник на самолета. 

Сортиране с приоритетна опашка
  1. Добавяме елементите един по един със серия от insertItem(e,e) операции.
  2. Премахваме елементите в нарастващ ред със серия от removeMin() операции.
  • Времето за работа на този метод на сортиране зависи от реализацията на приоритетната опашка АТД.
  • Algorithm PriorityQueueSort(S, P):
    Input: A sequence S storing n elements, on which a total order relation is
        defined, and a priority queue P, that compares keys using the same total order relation
    Output: The sequence S sorted by the total order relation
    while !S.isEmpty() do
       e <- S.removeFirst()   {remove an element e from
    S}
       
    P.insertItem(e,e)         {the key is the element itself}
    while !
    P.isEmpty() do
       
    e <- P.minElement()    {get a smallest element from P}
       
    P.removeMin()               {remove this element from P}
       
    S.insertLast(e)             {add the element at the end of S}
    Operation
    Output
    Priority Queue
    insertItem(5,A)
    -
    {(5,A)}
    insertItem(9,C) -
    {(5,A),(9,C)}
    insertItem(3,B) -
    {(3,B),(5,A),(9,C)}
    insertItem(7,D) -
    {(3,B),(5,A),(7,D),(9,C)}
    minElement()
    B
    {(3,B),(5,A),(7,D),(9,C)}
    minKey()
    3
    {(3,B),(5,A),(7,D),(9,C)}
    removeMin()
    -
    {(5,A),(7,D),(9,C)}
    size()
    3
    {(5,A),(7,D),(9,C)}
    minElement()
    A
    {(5,A),(7,D),(9,C)}
    removeMin()
    -
    {(7,D),(9,C)}
    removeMin() -
    {(9,C)}
    removeMin() -
    {}
    removeMin() ERROR
    {}
    isEmpty()
    true
    {}

    Все още има два важни въпроса, които са останали неопределени до този момент:
    Композиции и компаратори

    Композиция-шаблон
    html-7.2 (Item)

    Компаратор
    bool operator<(const Point& p1, const Point& p2)
    { if (p1.getX() == p2.getX()) return p1.getY() < p2.getY();
    else return p1.getX() < p1.getX();
    }
    class LexCompare {
    public:
    int operator()(Point a, Point b) {
    if (a.x < b.x) return –1
    else if (a.x > b.x) return +1

    else if (a.y < b.y) return –1
    else if (a.y > b.y) return +1
    else return 0;
    }
    };
    html-7.3 (Compare)

    Използване на компаратора

    Point p(2.3, 4.5);
    Point q(1.7, 7.3);
    LexCompare lexCompare;
    if (lexCompare(p, q) < 0) cout << “p less than q”;
    else if (lexCompare(p, q) == 0) cout << “p equals q”;
    else if (lexCompare(p, q) > 0) cout << “p greater than q”;
    html-7.4 (Generic)


    Реализация на приоритетна опашка АТД с редица АТД

    Реализация е несортирана редица Реализация със сортирана редица html-7.5 (SSPQ1)
    html-7.6 (SSPQ2)

    [priority.cpp]

    Сравнение на двете реализации

    • Реализация с ненаредена редица
      • Съхранява обектите на приоритетната редица в редица АТД, (реализирана със свързан списък) в произволен ред.
    • Реализация с наредена редица
      • Съхранява обектите на приоритетната редица в редица АТД, сортирани по ключ
    • Бързодействие:
      • insertItem отнема време O(1), защото обектът може да се добави в началото или в края на редицата;
      • removeMin, minKey и minElement отнемат време O(n), защото трябва да се обходи цялата редица за да се намери най-малкия ключ.
    • Бързодействие:
      • insertItem отнема време O(n), защото трябва да се намери мястото, където да се вмъкне новия обект;
      • removeMin, minKey и minElement отнемат време O(1), защото най-малкият ключ е в началото на редицата.

    Сортиране  чрез избор (Selection-Sort)
    1. Вмъкване на обектите в приоритетната опашка с n insertItem операции отнема време O(n).
    2. Изваждане на обект в нарастващ ред от приоритетната опашка с n операции removeMin отнема време, пропорционално на 1 + 2 + …+ n.
  • Сортитане чрез избор се изпълнява за време O(n2).

  • Sequence S
    Priority Queue P  (unsorted sequence)
    Input
    (7,4,8,2,5,3,9)
    ()
    Phase 1
    O(n)
    (4,8,2,5,3,9)
    (8,2,5,3,9)
    (2,5,3,9)
    (5,3,9)
    (3,9)
    (9)
    ()
    (7)
    (7,4)
    (7,4,8)
    (7,4,8,2)
    (7,4,8,2,5)
    (7,4,8,2,5,3)
    (7,4,8,2,5,3,9)
    Phase 2
    O(n2)
    (2)
    (2,3)
    (2,3,4)
    (2,3,4,5)
    (2,3,4,5,7)
    (2,3,4,5,7,8)
    (2,3,4,5,7,8,9)
    (7,4,8,5,3,9)
    (7,4,8,5,9)
    (7,8,5,9)
    (7,8,9)
    (8,9)
    (9)
    ()

    Сортиране чрез вмъкване (Insertion-Sort)

    1. Вмъкване на обектите в приоритетната опашка с n операции insertItem отнема време, пропорционално на 1 + 2 + …+ n.
    2. Изваждане на обект (в нарастващ ред) от приоритетната опашка със серия от n removeMin операции отнема време O(n).
  • Сортиране чрез вмъкване се изпълнява за време O(n2).

  • Sequence S
    Priority Queue P  (sorted sequence)
    Input
    (7,4,8,2,5,3,9)
    ()
    Phase 1
    O(n2)
    (4,8,2,5,3,9)
    (8,2,5,3,9)
    (2,5,3,9)
    (5,3,9)
    (3,9)
    (9)
    ()
    (7)
    (4,7)
    (4,7,8)
    (2,4,7,8)
    (2,4,5,7,8)
    (2,3,4,5,7,8)
    (2,3,4,5,7,8,9)
    Phase 2
    O(n)
    (2)
    (2,3)
    (2,3,4)
    (2,3,4,5)
    (2,3,4,5,7)
    (2,3,4,5,7,8)
    (2,3,4,5,7,8,9)
    (3,4,5,7,8,9)
    (4,5,7,8,9)
    (5,7,8,9)
    (7,8,9)
    (8,9)
    (9)
    ()