forked from JaredBahor/CSE
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPriorityQueue.c
More file actions
177 lines (165 loc) · 5.93 KB
/
PriorityQueue.c
File metadata and controls
177 lines (165 loc) · 5.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include <stdlib.h>
#include <stdbool.h>
#include "priority_queue.h"
/*
* Create a new PriorityQueue structure and return it.
*
* The newly-created structure should have a NULL head, and every tail
* pointer in its tails table should be NULL.
*
* nprios: The maximum number of priorities to support
*/
PriorityQueue *pqueue_init(int nprios) {
if(nprios <= 0){
return NULL;
}else {
struct PriorityQueue* pq = (PriorityQueue*)malloc(sizeof(PriorityQueue));
pq -> head = NULL;
pq -> nprios = nprios;
struct PQNode** arr = (PQNode**)malloc(sizeof(PQNode*) * nprios);
pq->tails = arr;
for (int i = 0; i < nprios; i++){
pq->tails[i] = NULL;
//*(arr + i) = NULL; //same as line 19
}
return pq;
}
}
/*
* Free all structures associated with this priority queue, including their
* queue structure itself. Any access to pqueue after this function returns
* should be considered invalid.
*
* pqueue: the queue to free
*/
//Step 1) Set tails array to NULL, then free tails array.
//Step 2) Iterate pqueue to free each individual node.
//Step 3) Free the pqueue structure itself.
void pqueue_free(PriorityQueue *pqueue) {
for (int i = 0; i < pqueue->nprios; i++){//set each pointer to NULL
pqueue->tails[i] = NULL;
}
free(pqueue->tails);
//Step 1 ^^
PQNode* node = pqueue->head;
PQNode* freed = pqueue->head;
while(node->next != NULL){
freed = node;
free(freed);
node = node->next;
}
free(node);
//Step 2 ^^
free(pqueue);
//Step 3 ^^
}
/*
* Insert a new node into a queue by priority and value.
*
* pqueue: the queue into which the new node should be inserted
* value: the opaque value being inserted into the queue
* priority: the priority at which this value is to be inserted
*/
void pqueue_insert(PriorityQueue *pqueue, int value, int priority) {
if (pqueue != NULL){
if (priority <= pqueue->nprios - 1 && priority >= 0){
PQNode* pq = pqueue->head;
if (pq == NULL){// empty queue
PQNode* newNode = (PQNode*)malloc(sizeof(PQNode));
newNode->priority = priority;
newNode->value = value;
newNode->prev = NULL;
newNode->next = NULL;
pqueue->tails[priority] = newNode;//make newNode tail
pqueue->head = newNode;//make newNode head
}else{
if (pqueue->tails[priority] != NULL){
PQNode* newNode = (PQNode*)malloc(sizeof(PQNode));
PQNode* prev = pqueue->tails[priority];
PQNode* next = pqueue->tails[priority]->next;//could be NULL
newNode->priority = priority;
newNode->value = value;
newNode->next = next;
newNode->prev = prev;
prev->next = newNode;
if (next != NULL){
next->prev = newNode;
}
//next->prev = newNode;
pqueue->tails[priority] = newNode;
}else{//pqueue->tails[priority] == NULL
int i = 0;
for(i = priority; pqueue->tails[i] == NULL && i >= 0; i--);
if(i < 0){//the inserted node is the lowest prio (becomes the head)
PQNode* next = pqueue->head;
PQNode* prev = NULL;
PQNode* newNode = (PQNode*)malloc(sizeof(PQNode));
newNode->priority = priority;
newNode->value = value;
newNode->prev = prev;//NULL
newNode->next = next;//old head
next->prev = newNode;
pqueue->tails[priority] = newNode;
pqueue->head = newNode;
}else{//a tail comes before the inserted node
PQNode* prev = pqueue->tails[i];
PQNode* next = pqueue->tails[i]->next;//could be NULL
PQNode* newNode = (PQNode*)malloc(sizeof(PQNode));
newNode->priority = priority;
newNode->value = value;
newNode->prev = prev;
newNode->next = next;
prev->next = newNode;
if (next != NULL){
next->prev = newNode;
}
//next->prev = newNode;
pqueue->tails[priority] = newNode;
}
}
}
}
}
return;
}
/*
* Return the head queue node without removing it.
*/
PQNode *pqueue_peek(PriorityQueue *pqueue) {
if (pqueue == NULL){
return NULL;
}else if (pqueue->head != NULL){
return pqueue->head;
}else{
return NULL;
}
}
/*
* Remove and return the head queue node.
*/
PQNode *pqueue_get(PriorityQueue *pqueue) {
if (pqueue->head != NULL && pqueue != NULL){
PQNode* head = pqueue->head;
PQNode* next = pqueue->head->next;
PQNode* tmp = pqueue->head;
int prio = pqueue->head->priority;
if (next != NULL){//has more than just head
if (pqueue->tails[prio] == head){//the head is the tail for the prio
pqueue->head = head->next;
next->prev = NULL;
pqueue->tails[prio] = NULL;
return tmp;
}else{//the head is not the tail for the prio
pqueue->head = head->next;
next->prev = NULL;
return tmp;
}
}else{//only 1 Node (head node)
pqueue->head = NULL;//set head to NULL
pqueue->tails[prio] = NULL;//set tail to NULL
return tmp;//return original head
}
}else {
return NULL;
}
}