-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
queue.h
255 lines (231 loc) · 7.23 KB
/
queue.h
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#ifndef LAB0_QUEUE_H
#define LAB0_QUEUE_H
/* This program implements a queue supporting both FIFO and LIFO
* operations.
*
* It uses a circular doubly-linked list to represent the set of queue elements
*/
#include <stdbool.h>
#include <stddef.h>
#include "harness.h"
#include "list.h"
/**
* element_t - Linked list element
* @value: pointer to array holding string
* @list: node of a doubly-linked list
*
* @value needs to be explicitly allocated and freed
*/
typedef struct {
char *value;
struct list_head list;
} element_t;
/**
* queue_contex_t - The context managing a chain of queues
* @q: pointer to the head of the queue
* @chain: used by chaining the heads of queues
* @size: the length of this queue
* @id: the unique identification number
*/
typedef struct {
struct list_head *q;
struct list_head chain;
int size;
int id;
} queue_contex_t;
/* Operations on queue */
/**
* q_new() - Create an empty queue whose next and prev pointer point to itself
*
* Return: NULL for allocation failed
*/
struct list_head *q_new();
/**
* q_free() - Free all storage used by queue, no effect if header is NULL
* @head: header of queue
*/
void q_free(struct list_head *head);
/**
* q_insert_head() - Insert an element in the head
* @head: header of queue
* @s: string would be inserted
*
* Argument s points to the string to be stored.
* The function must explicitly allocate space and copy the string into it.
*
* Return: true for success, false for allocation failed or queue is NULL
*/
bool q_insert_head(struct list_head *head, char *s);
/**
* q_insert_tail() - Insert an element at the tail
* @head: header of queue
* @s: string would be inserted
*
* Argument s points to the string to be stored.
* The function must explicitly allocate space and copy the string into it.
*
* Return: true for success, false for allocation failed or queue is NULL
*/
bool q_insert_tail(struct list_head *head, char *s);
/**
* q_remove_head() - Remove the element from head of queue
* @head: header of queue
* @sp: string would be inserted
* @bufsize: size of the string
*
* If sp is non-NULL and an element is removed, copy the removed string to *sp
* (up to a maximum of bufsize-1 characters, plus a null terminator.)
*
* NOTE: "remove" is different from "delete"
* The space used by the list element and the string should not be freed.
* The only thing "remove" need to do is unlink it.
*
* Reference:
* https://english.stackexchange.com/questions/52508/difference-between-delete-and-remove
*
* Return: the pointer to element, %NULL if queue is NULL or empty.
*/
element_t *q_remove_head(struct list_head *head, char *sp, size_t bufsize);
/**
* q_remove_tail() - Remove the element from tail of queue
* @head: header of queue
* @sp: string would be inserted
* @bufsize: size of the string
*
* Return: the pointer to element, %NULL if queue is NULL or empty.
*/
element_t *q_remove_tail(struct list_head *head, char *sp, size_t bufsize);
/**
* q_release_element() - Release the element
* @e: element would be released
*
* This function is intended for internal use only.
*/
static inline void q_release_element(element_t *e)
{
test_free(e->value);
test_free(e);
}
/**
* q_size() - Get the size of the queue
* @head: header of queue
*
* Return: the number of elements in queue, zero if queue is NULL or empty
*/
int q_size(struct list_head *head);
/**
* q_delete_mid() - Delete the middle node in queue
* @head: header of queue
*
* The middle node of a linked list of size n is the
* ⌊n / 2⌋th node from the start using 0-based indexing.
* If there're six elements, the third member should be returned.
*
* Reference:
* https://leetcode.com/problems/delete-the-middle-node-of-a-linked-list/
*
* Return: true for success, false if list is NULL or empty.
*/
bool q_delete_mid(struct list_head *head);
/**
* q_delete_dup() - Delete all nodes that have duplicate string,
* leaving only distinct strings from the original queue.
* @head: header of queue
*
* Reference:
* https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/
*
* Return: true for success, false if list is NULL or empty.
*/
bool q_delete_dup(struct list_head *head);
/**
* q_swap() - Swap every two adjacent nodes
* @head: header of queue
*
* Reference:
* https://leetcode.com/problems/swap-nodes-in-pairs/
*/
void q_swap(struct list_head *head);
/**
* q_reverse() - Reverse elements in queue
* @head: header of queue
*
* No effect if queue is NULL or empty.
* This function should not allocate or free any list elements
* (e.g., by calling q_insert_head, q_insert_tail, or q_remove_head).
* It should rearrange the existing ones.
*/
void q_reverse(struct list_head *head);
/**
* q_reverseK() - Given the head of a linked list, reverse the nodes of the list
* k at a time.
* @head: header of queue
* @k: is a positive integer and is less than or equal to the length of the
* linked list.
*
* No effect if queue is NULL or empty. If there has only one element, do
* nothing.
*
* Reference:
* https://leetcode.com/problems/reverse-nodes-in-k-group/
*/
void q_reverseK(struct list_head *head, int k);
/**
* q_sort() - Sort elements of queue in ascending/descending order
* @head: header of queue
* @descend: whether or not to sort in descending order
*
* No effect if queue is NULL or empty. If there has only one element, do
* nothing.
*/
void q_sort(struct list_head *head, bool descend);
/**
* q_ascend() - Remove every node which has a node with a strictly less
* value anywhere to the right side of it.
* @head: header of queue
*
* No effect if queue is NULL or empty. If there has only one element, do
* nothing.
* Memory allocated to removed nodes must be freed.
*
* Reference:
* https://leetcode.com/problems/remove-nodes-from-linked-list/
*
* Return: the number of elements in queue after performing operation
*/
int q_ascend(struct list_head *head);
/**
* q_descend() - Remove every node which has a node with a strictly greater
* value anywhere to the right side of it.
* @head: header of queue
*
* No effect if queue is NULL or empty. If there has only one element, do
* nothing.
* Memory allocated to removed nodes must be freed.
*
* Reference:
* https://leetcode.com/problems/remove-nodes-from-linked-list/
*
* Return: the number of elements in queue after performing operation
*/
int q_descend(struct list_head *head);
/**
* q_merge() - Merge all the queues into one sorted queue, which is in
* ascending/descending order.
* @head: header of chain
* @descend: whether to merge queues sorted in descending order
*
* This function merge the second to the last queues in the chain into the first
* queue. The queues are guaranteed to be sorted before this function is called.
* No effect if there is only one queue in the chain. Allocation is disallowed
* in this function. There is no need to free the 'queue_contex_t' and its
* member 'q' since they will be released externally. However, q_merge() is
* responsible for making the queues to be NULL-queue, except the first one.
*
* Reference:
* https://leetcode.com/problems/merge-k-sorted-lists/
*
* Return: the number of elements in queue after merging
*/
int q_merge(struct list_head *head, bool descend);
#endif /* LAB0_QUEUE_H */