master
  1#include "priority_queue.h"
  2#include <stdio.h>
  3#include <stdlib.h>
  4
  5/**
  6 * The equivalent of a constructor to create a PriorityQueue.
  7 */
  8PriorityQueue *initialize(void) {
  9  PriorityQueue *self = malloc(sizeof(PriorityQueue));
 10  self->size = 0;
 11  self->head = NULL;
 12  return self;
 13}
 14
 15/**
 16 * A function used to construct a Node for a singly linked list.
 17 *
 18 * @param priority the priority for the data
 19 * @param data the data to store in the queue
 20 * @return The Node to add to a singly linked list.
 21 */
 22static Node *create_node(int priority, int data) {
 23  Node *node = malloc(sizeof(Node));
 24  node->priority = priority;
 25  node->data = data;
 26  node->next = NULL;
 27  return node;
 28}
 29
 30/**
 31 * Determines the number of items stored in a queue.
 32 *
 33 * @param self The queue to investigate
 34 * @return The total number of items stored in the queue.
 35 */
 36int size(PriorityQueue *self) { return self->size; }
 37
 38/**
 39 * Compares two integers and returns:
 40 * 1 if x is greater than y.
 41 * 0 if x is equal to y.
 42 * -1 if x is less than to y.
 43 *
 44 *  @param x the integer to compare
 45 *  @param y the other integer to compare
 46 *  @return 1,0,-1 depending on the comparison of x and y
 47 */
 48static int compare(const int x, const int y) {
 49  return x == y ? 0 : x > y ? 1 : -1;
 50}
 51
 52/**
 53 * Inserts a node into the queue in the best position based on the priority.
 54 *
 55 * @param self The head of the queue.
 56 * @param priority The priority of the data.
 57 * @param data the data to store.
 58 */
 59void enqueue(Node *self, int priority, int data) {
 60  if (self->next == NULL) {
 61    self->next = create_node(priority, data);
 62    return;
 63  }
 64
 65  int comparison = compare(self->next->priority, priority);
 66  if (comparison == 0) {
 67    return enqueue(self->next, priority, data);
 68  }
 69
 70  if (comparison < 0) {
 71    return enqueue(self->next, priority, data);
 72  }
 73
 74  Node *tmp = self->next;
 75  self->next = create_node(priority, data);
 76  self->next->next = tmp;
 77}
 78
 79/**
 80 * Adds data with a specific priority to the queue
 81 *
 82 * @param self The queue to add data to
 83 * @param priority The priority for the data
 84 * @param data The data to store
 85 */
 86void add(PriorityQueue *self, int priority, int data) {
 87  self->size++;
 88
 89  if (!self->head) {
 90    self->head = create_node(priority, data);
 91    return;
 92  }
 93
 94  if (compare(self->head->priority, priority) <= 0)
 95    return enqueue(self->head, priority, data);
 96
 97  Node *node = create_node(priority, data);
 98  node->next = self->head;
 99  self->head = node;
100}
101
102/**
103 * Removes the next item in the queue with the lowest priority.
104 *
105 * @param self The queue
106 * @return The data associated with the lowest priority in the queue
107 */
108int delete_min(PriorityQueue *self) {
109  if (self->head) {
110    Node *tmp = self->head;
111    int data = tmp->data;
112    self->head = tmp->next;
113    self->size--;
114    free(tmp);
115    return data;
116  }
117  return 0;
118}
119
120/**
121 * A helper function used to print a queue.
122 * This is useful for debugging.
123 *
124 * @param self The queue to print
125 */
126void inspect(PriorityQueue *self) {
127  Node *tmp = self->head;
128
129  printf("Items (%d): [ ", size(self));
130  while (tmp) {
131    printf("(%d,%d) ", tmp->priority, tmp->data);
132    tmp = tmp->next;
133  }
134  printf("]\n");
135}
136
137/**
138 * The equivalent of a destructor function.
139 * This function frees any memory associated with a queue
140 *
141 * @param self The queue to free
142 */
143void destroy(PriorityQueue *self) {
144  Node *current = self->head;
145  Node *tmp;
146
147  while (current) {
148    tmp = current, current = current->next;
149
150    if (tmp)
151      free(tmp);
152  }
153  free(self);
154}