-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathqueue.c
More file actions
160 lines (137 loc) · 3.6 KB
/
queue.c
File metadata and controls
160 lines (137 loc) · 3.6 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
#include "queue.h"
/**
* queue_new - allocate memory for an empty queue.
*
* Return: pointer to the new queue, NULL on failure.
*/
queue *queue_new(void) { return (_calloc(1, sizeof(queue))); }
/**
* queue_peek_head - returns pointer to the data at the head node.
* @q: pointer to the queue.
*
* Return: pointer to the data at the head of the queue.
*/
void *queue_peek_head(const queue *const q)
{
if (!q || !q->head)
return (NULL);
return (q->head->data);
}
/**
* queue_peek_tail - returns pointer to the data at the tail node.
* @q: pointer to the queue.
*
* Return: pointer to the data at the tail of the queue.
*/
void *queue_peek_tail(const queue *const q)
{
if (!q || !q->tail)
return (NULL);
return (q->tail->data);
}
/**
* enqueue - add a node to the end of a queue.
* @q: the queue to operate on.
* @data: data that the node will hold.
* @copy_data: function that returns a separate copy of data,
* if NULL a simple copy of the pointer to data is done.
*
* Return: pointer to the newly added node, NULL if q is NULL or failure.
*/
single_link_node *enqueue(
queue *const q, void *const data, dup_func *copy_data)
{
single_link_node *nw = NULL;
if (!q)
return (NULL);
nw = sln_new(data, copy_data);
if (!nw)
return (NULL);
q->tail = sln_insert_after(q->tail, nw);
if (!q->head)
q->head = nw;
++(q->length);
return (nw);
}
/**
* dequeue - pop a node from the start of a queue and return its data.
* @q: the queue to operate on.
*
* Return: pointer to the data in the popped node, NULL if q or head is NULL.
*/
void *dequeue(queue *const q)
{
single_link_node *node = NULL;
void *d = NULL;
if (!q || !q->head)
return (NULL);
node = q->head;
q->head = node->next;
d = sln_remove(node);
if (!q->head)
q->tail = NULL;
if (q->length)
--(q->length);
return (d);
}
/**
* queue_clear - delete all items in a queue.
* @q: the queue to operate on.
* @free_data: pointer to a function that will be called to free data in nodes.
*/
void queue_clear(queue *const q, delete_func *free_data)
{
if (!q)
return;
q->head = sll_clear(q->head, free_data);
q->tail = NULL;
q->length = 0;
}
/**
* queue_delete - frees a queue from memory.
* @nullable_ptr: pointer to the queue to delete.
* @free_data: pointer to a function that can free data in the queue.
*
* Return: NULL always.
*/
void *queue_delete(queue *const nullable_ptr, delete_func *free_data)
{
queue_clear(nullable_ptr, free_data);
return (_free(nullable_ptr));
}
/**
* queue_to_array - create an array from a queue.
* @q: the queue.
* @copy_data: optional pointer to a function that will be used to duplicate
* the data, if not provided, array will contain pointers to the original data
* in the queue.
* @free_data: optional pointer to a function that will be used to free data in
* the array in case of failure. If `copy_data` is provided this function must
* also be provided, otherwise no data duplication will occur.
*
* Return: pointer to the data array on success, NULL on failure.
*/
void **queue_to_array(
const queue *const q, dup_func *copy_data, delete_func *free_data)
{
void **data_array = NULL;
single_link_node *node = NULL;
intmax_t d_i = 0;
if (!q || !q->head || q->length < 1)
return (NULL);
data_array = _calloc(q->length + 1, sizeof(*data_array));
if (!data_array)
return (NULL);
node = q->head;
for (d_i = 0; node; node = node->next, ++d_i)
{
data_array[d_i] = node->data;
if (copy_data && free_data)
{
data_array[d_i] = copy_data(node->data);
if (!data_array[d_i] && node->data)
return (delete_2D_array(data_array, q->length, free_data));
}
}
return (data_array);
}