简体   繁体   中英

Unsorted doubly linked list for priority queue of strings in C++

I am trying to implement a "priority" queue of strings with an unsorted doubly linked list but I am totally stuck on the dequeue method (at the bottom of the code / there might be issues before however). By priority queue I mean a queue in which the first element to be dequeued is the minimum element.

Would you mind having a look at my code and give me few hints on where I am wrong?

Thanks a lot for your help.

matt

/*************************************************************
 * File: pqueue-doublylinkedlist.cpp
 *
 * Implementation file for the DoublyLinkedListPriorityQueue
 * class.
 */

#include "pqueue-doublylinkedlist.h"
#include "error.h"

/* Implementation notes: DoublyLinkedListPriorityQueue constructor
 * ----------------------------------------------------------------
 * This function initializes an empty priority queue represented as a doubly 
 * linked-list.
 */

DoublyLinkedListPriorityQueue::DoublyLinkedListPriorityQueue() {
    listHead = new Cell;
    listHead = NULL;
    count = 0;
}

/* Implementation notes: DoublyLinkedListPriorityQueue destructor
 * --------------------------------------------------------------
 * This function deletes every cell in the priority queue.
 */

DoublyLinkedListPriorityQueue::~DoublyLinkedListPriorityQueue() {
    Cell *temp, *link;
    temp = link = new Cell;

    temp = listHead;
    while (temp != NULL) {
        link = temp->next;
        delete temp;
        temp = link;
    }
    count = 0;
}

/* Implementation notes: DoublyLinkedListPriorityQueue size
 * --------------------------------------------------------
 * Returns the size of the priority queue.
 */

int DoublyLinkedListPriorityQueue::size() {
    return count;
}

/* Implementation notes: DoublyLinkedListPriorityQueue isEmpty
 * -----------------------------------------------------------
 * Returns true if there is no cell within the list.
 */

bool DoublyLinkedListPriorityQueue::isEmpty() {
    return (count == 0);
}

/* Implementation notes: DoublyLinkedListPriorityQueue enqueue
 * -----------------------------------------------------------
 * Enqueues the new Cell into the chain just after the head Cell.
 */

void DoublyLinkedListPriorityQueue::enqueue(string value) {

    Cell *newOne = new Cell;
    newOne->str = value;
    newOne->prev = NULL;

    newOne->next = listHead;
    listHead = newOne;

    count++;
}

/* Implementation notes: DoublyLinkedListPriorityQueue peek
 * --------------------------------------------------------
 * Returns the string value of the next node to be dequeued.
 */

string DoublyLinkedListPriorityQueue::peek() {
    if (isEmpty()) error("peek an empty list");

    curr = new Cell;

    curr = listHead;
    string result = listHead->str;

    for (curr = listHead; curr != NULL; curr = curr->next) {
        if (curr->str != "" && curr->str < result) {
            result = curr->str;
        }
    }

    return result;
}

/* Implementation notes: DoublyLinkedListPriorityQueue dequeueMin
 * --------------------------------------------------------------
 * Deletes the node with the smallest string and returns this string value.
 */

string DoublyLinkedListPriorityQueue::dequeueMin() {
    if (isEmpty()) error("dequeueMin an empty list");

    Cell *temp;
    temp = curr = new Cell;
    temp = curr = NULL;

    string result = listHead->str;

    // find the node to delete and store a pointer on it
    for (curr = listHead; curr != NULL; curr = curr->next) {
        if (curr->str != "" && curr->str < result) {
            result = curr->str;
            temp = curr;
        }
    }

    // first position (if: node to delete prev == NULL)
    if (temp->prev == NULL) {
        temp = listHead->next;
        delete listHead;
        listHead = temp;

    // delete from last position (else if: node to delete next == NULL)
    } else if (temp->next == NULL) {
        curr = temp->prev;
        curr->next = NULL;
        delete temp;

    // other position (else)
    } else {
        temp->prev->next = temp->next;
        temp->next->prev = temp->prev;
        delete temp;
    }

    count--;

    return result;
}

Implementing a priority queue as a doubly-linked list (or, indeed, implementing one at all) is pretty unusual, since there's an STL implementation available to use:

#include <iostream>
#include <queue>
#include <functional>

int main(void) {
    std::priority_queue<std::string, std::vector<std::string>,
            std::greater<std::string> > pq;

    pq.push("foo");
    pq.push("bar");
    pq.push("quux");

    while( !pq.empty() ) {
        std::cout << pq.top() << std::endl;
        pq.pop();
    }

    return 0;
}

I'm posting this on the assumption that, perhaps, you simply didn't know that this functionality was available, rather than there there is a real reason why you want to do your own implementation and do it in a rather odd way.

If I'm wrong, and the above pointer is no use to you, I'd recommend adapting your implementation to the interface of the standard version (as much as you can) and explaining why you don't want to use the STL version, as these steps will increase the familiarity of your code for StackOverflow users (both those who might answer your question better than I can, and future users with similar questions).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM