-
Notifications
You must be signed in to change notification settings - Fork 0
/
SPBPriorityQueue.c
194 lines (159 loc) · 4.19 KB
/
SPBPriorityQueue.c
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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/*
* SBPPriorityQueue.c
*
* Created on: Jun 3, 2016
* Author: mataneilat
*/
#include "SPBPriorityQueue.h"
#include "SPList.h"
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
/*** Method declaration ***/
SPBPQueue spBPQueueInnerCreate(SPList innerList, int maxSize);
SPListElement spBPQueueFirstElement(SPBPQueue source);
SPListElement spBPQueueLastElement(SPBPQueue source);
struct sp_bp_queue_t {
SPList innerList;
int maxSize;
};
SPBPQueue spBPQueueCreate(int maxSize) {
if (maxSize <= 0) {
return NULL;
}
SPList newList = spListCreate();
if (newList == NULL) {
return NULL;
}
SPBPQueue createdQueue = spBPQueueInnerCreate(newList, maxSize);
if (createdQueue == NULL) {
spListDestroy(newList);
return NULL;
}
return createdQueue;
}
SPBPQueue spBPQueueInnerCreate(SPList innerList, int maxSize) {
SPBPQueue createdQueue = (SPBPQueue) malloc(sizeof(*createdQueue));
if (createdQueue == NULL) {
return NULL;
}
createdQueue->innerList = innerList;
createdQueue->maxSize = maxSize;
return createdQueue;
}
SPBPQueue spBPQueueCopy(SPBPQueue source) {
if (source == NULL) {
return NULL;
}
SPList listCopy = spListCopy(source->innerList);
if (listCopy == NULL) {
return NULL;
}
return spBPQueueInnerCreate(listCopy, source->maxSize);
}
void spBPQueueDestroy(SPBPQueue source) {
if (source == NULL) {
return;
}
spListDestroy(source->innerList);
free(source);
}
void spBPQueueClear(SPBPQueue source) {
if (source == NULL) {
return;
}
spListClear(source->innerList);
}
int spBPQueueSize(SPBPQueue source) {
return source == NULL ? -1 : spListGetSize(source->innerList);
}
int spBPQueueGetMaxSize(SPBPQueue source) {
return source == NULL ? -1 : source->maxSize;
}
SP_BPQUEUE_MSG spBPQueueEnqueue(SPBPQueue source, SPListElement element) {
if (source == NULL || element == NULL) {
return SP_BPQUEUE_INVALID_ARGUMENT;
}
bool wasFull = spBPQueueIsFull(source);
SPList list = source->innerList;
bool wasInserted = false;
// Advance iterator to the proper element's place
SP_LIST_FOREACH(SPListElement, currentElement, list) {
if (spListElementCompare(element, currentElement) < 0) {
// Modifying while iterating - bad practice but is more efficient here.
SP_LIST_MSG returnMSG = spListInsertBeforeCurrent(list, element);
switch (returnMSG) {
case SP_LIST_OUT_OF_MEMORY:
return SP_BPQUEUE_OUT_OF_MEMORY;
default:
break;
}
wasInserted = true;
break;
}
}
if (wasInserted) {
// Remove the last element if needed
if (wasFull) {
spListGetLast(list);
spListRemoveCurrent(list);
}
return SP_BPQUEUE_SUCCESS;
} else {
if (spBPQueueIsFull(source)) {
return SP_BPQUEUE_FULL;
} else {
// The item is largest than everything, insert last
SP_LIST_MSG returnMSG = spListInsertLast(list, element);
switch (returnMSG) {
case SP_LIST_OUT_OF_MEMORY:
return SP_BPQUEUE_OUT_OF_MEMORY;
default:
return SP_BPQUEUE_SUCCESS;
}
}
}
}
SP_BPQUEUE_MSG spBPQueueDequeue(SPBPQueue source) {
if (source == NULL) {
return SP_BPQUEUE_INVALID_ARGUMENT;
}
if (spBPQueueIsEmpty(source)) {
return SP_BPQUEUE_EMPTY;
}
spListGetFirst(source->innerList);
spListRemoveCurrent(source->innerList);
return SP_BPQUEUE_SUCCESS;
}
SPListElement spBPQueuePeek(SPBPQueue source) {
return spListElementCopy(spBPQueueFirstElement(source));
}
SPListElement spBPQueuePeekLast(SPBPQueue source) {
return spListElementCopy(spBPQueueLastElement(source));
}
double spBPQueueMinValue(SPBPQueue source) {
return spListElementGetValue(spBPQueueFirstElement(source));
}
double spBPQueueMaxValue(SPBPQueue source) {
return spListElementGetValue(spBPQueueLastElement(source));
}
bool spBPQueueIsEmpty(SPBPQueue source) {
assert(source != NULL);
return spBPQueueSize(source) == 0;
}
bool spBPQueueIsFull(SPBPQueue source) {
assert(source != NULL);
return spBPQueueSize(source) == spBPQueueGetMaxSize(source);
}
SPListElement spBPQueueFirstElement(SPBPQueue source) {
if (source == NULL || spBPQueueIsEmpty(source)) {
return NULL;
}
return spListGetFirst(source->innerList);
}
SPListElement spBPQueueLastElement(SPBPQueue source) {
if (source == NULL || spBPQueueIsEmpty(source)) {
return NULL;
}
return spListGetLast(source->innerList);
}