1

So I'm trying to create this priority queue to handle my "Order" objects, I'm running into a problem where an object containing the same key/priority will be placed at an early earlier position than others initialized first. I have provided the expected and received output alongside the 83 lines of code of how I constructed my heap with notes

#include <iostream>
#include <vector>

struct Order {
    int value = -1;
    int priority = -1;
    bool operator <(Order const& RHS) { return priority < RHS.priority; } 
};

class heap {
private:
    std::vector<Order> orders{ Order{} };
    int size{}; //initalizes it at 0
    int p(int index) { return index >> 1; } 
    int l(int index) { return index << 1; } 
    int r(int index) { return (index << 1) + 1; } 
public:
    bool isEmpty() const { return size == 0; }
    void shiftUp(int position);
    void shiftDown(int position);
    void add(Order new_entry);
    Order removeTop();
    Order& getTop() { return orders[1]; }
}; 

template <typename T> 
void mySwap(T& a, T& b) {
    T temp = a;
    a = b;
    b = temp;
}

int main() {
    heap h;
    h.add(Order{1,3}); h.add(Order{2,2});
    h.add(Order{3,3}); h.add(Order{5,1});
    h.add(Order{6,2}); h.add(Order{7,2});
    h.add(Order{8,3}); h.add(Order{9,1});
    h.add(Order{23,3}); 
    std::cout << "value" << "     key(priority)" << "\n";
    for (int i = 0; i < 8; i++) {
        Order temp = h.removeTop();
        std::cout << temp.value << "\t    " << temp.priority << "\n";
    }
}

void heap::shiftUp(int position) {
    if (position > size) return; 
    if (position == 1) return; 
    if (orders[p(position)] < orders[position]) { 
        mySwap(orders[position], orders[p(position)]);
        shiftUp(p(position));
    }
}

void heap::shiftDown(int position) {
    if (position > size) return; 
    int greaterPosition = position;
    if (l(position) <= size && orders[position] < orders[l(position)]) 
        greaterPosition = l(position);
    if (r(position) <= size && orders[greaterPosition] < orders[r(position)]) 
        greaterPosition = r(position);
    if (greaterPosition != position) { 
        mySwap(orders[position], orders[greaterPosition]);
        shiftDown(greaterPosition);
    }
}

void heap::add(Order new_entry) {
    if (size + 1 >= orders.size()) orders.push_back(Order{}); 

    orders[++size] = new_entry; 
    shiftUp(size); 
}

Order heap::removeTop() {
    Order temp = orders[1];
    mySwap(orders[1],orders[orders.size() - 1]); size--; 
    orders.pop_back(); 
    shiftDown(1); 
    return temp;
}

/*
        Expected Output

    Value           key(priority)
    1                   3
    3                   3
    8                   3
    23                  3
    2                   2
    6                   2
    7                   2
    5                   1
    9                   1


    Recieved/wrong Output

    value            key(priority)
    1                   3
    23                  3
    3                   3
    8                   3
    2                   2
    6                   2
    7                   2
    5                   1

*/ 
Brett
  • 41
  • 6

2 Answers2

1

Fixed code from answered information above

#include <iostream>
#include <vector>

struct Order {
    int value = -1;
    int priority = -1;
    int FIFO;
    bool operator <(Order const& RHS) {
        if (priority == RHS.priority)
            return FIFO > RHS.FIFO;
        else
            return priority < RHS.priority;
    } //compares keys for larger presidence 
};

class heap {
private:
    std::vector<Order> orders{ Order{} };
    int size{}; //initalizes it at 0
    int p(int index) { return index >> 1; } 
    int l(int index) { return index << 1; }  
    int r(int index) { return (index << 1) + 1; } 
public:
    bool isEmpty() const { return size == 0; }
    void shiftUp(int position);
    void shiftDown(int position);
    void add(Order new_entry);
    Order removeTop();
    Order& getTop() { return orders[1]; }
}; 

template <typename T> 
void mySwap(T& a, T& b) {
    T temp = a;
    a = b;
    b = temp;
}

int main() {
    heap h;
    h.add(Order{1,3}); h.add(Order{2,2});
    h.add(Order{3,3}); h.add(Order{5,1});
    h.add(Order{6,2}); h.add(Order{7,2});
    h.add(Order{8,3}); h.add(Order{9,1});
    h.add(Order{23,3}); 
    std::cout << "value" << "     key(priority)" << "\n";
    for (int i = 0; i < 8; i++) {
        Order temp = h.removeTop();
        std::cout << temp.value << "\t    " << temp.priority << "\n";
    }
}

void heap::shiftUp(int position) {
    if (position > size) return; 
    if (position == 1) return; 
    if (orders[p(position)] < orders[position]) { 
        mySwap(orders[position], orders[p(position)]);
        shiftUp(p(position));
    }
}

void heap::shiftDown(int position) {
    if (position > size) return; 
    int greaterPosition = position;
    if (l(position) <= size && orders[position] < orders[l(position)]) 
        greaterPosition = l(position);
    if (r(position) <= size && orders[greaterPosition] < orders[r(position)]) 
        greaterPosition = r(position);
    if (greaterPosition != position) { 
        mySwap(orders[position], orders[greaterPosition]);
        shiftDown(greaterPosition);
    }
}

void heap::add(Order new_entry) {
    if (size + 1 >= orders.size()) orders.push_back(Order{});
    new_entry.FIFO = size + 1;
    orders[++size] = new_entry; 
    shiftUp(size); 
}

Order heap::removeTop() {
    Order temp = orders[1];
    mySwap(orders[1],orders[orders.size() - 1]); size--; 
    orders.pop_back(); 
    shiftDown(1); 
    return temp;
}

Brett
  • 41
  • 6
1

In general, heap does not have FIFO property until you implement something that helps doing so. In your order class, you are only comparing using the priority value. In your Order class, you are comparing two Orders by only their priority value. You need a additional variable that serves as the purpose for recording the timing when that value was inserted, and compare according to that.

If you are using the variable value for that purpose, you need to specify in your overloaded < method, what do you want to do when two Order's priority values are equal. Currently, you are only using the priority variable to compare. You are not specifying what do you want to do when the priority of two Orders are equal. You have to specify what do you want to do when the priority value of two variables are equal. Maybe compare a timing variable.

  • Thank you so much, it worked! I was struggling on that for the longest time! I posted the changes to my code below – Brett May 29 '20 at 10:58