-
Notifications
You must be signed in to change notification settings - Fork 0
/
list.h
146 lines (116 loc) · 6.29 KB
/
list.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
// List data type
// You may modify this file as needed; however,
// you may *NOT* modify the function prototypes or constant names.
#ifndef _LIST_H_
#define _LIST_H_
#include <stdbool.h>
#include <stddef.h>
typedef struct Node_s Node;
struct Node_s {
// Pointer to an item of any type
void* pItem;
// If the node is in a list, this is a pointer to the next node in the list
// Set to NULL if the node is the last node in the list
// If the node is available, this is a pointer to the next available node in the linked chain of available nodes
// Set to NULL if the node is the last node in the linked chain of available nodes
Node* pNextNode;
// Pointer to the previous node in the list
// Set to NULL if the node is the first node in the list
Node* pPrevNode;
};
typedef struct List_s List;
struct List_s {
// A pointer to the next available list head in the linked chain of available list heads
// NULL if the list head is the last list head in the linked chain of available list heads
List* pNextHead;
// Number of items in the list
int size;
// Pointer to the current node in the list
// Points to a special dummy node if the current item is before the start of the list
// Points to another special dummy node if the current item is beyond the end of the list
Node* pCurrentNode;
// Pointer to the first node in the list
// Set to NULL if the list is empty
Node* pHeadNode;
// Pointer to the last node in the list
// Set to NULL if the list is empty
Node* pTailNode;
};
// Maximum number of unique lists the system can support
// (You may modify its value for your needs)
#define LIST_MAX_NUM_HEADS 10
// Maximum total number of nodes (statically allocated) to be shared across all lists
// (You may modify its value for your needs)
#define LIST_MAX_NUM_NODES 1000
// General Error Handling:
// Client code is assumed never to call these functions with a NULL List pointer, or
// bad List pointer. If it does, any behaviour is permitted (such as crashing).
// HINT: Use assert(pList != NULL); just to add a nice check, but not required.
// Makes a new, empty list, and returns its reference on success.
// Returns a NULL pointer on failure.
List* List_create();
// Returns the number of items in pList.
int List_count(List* pList);
// Returns a pointer to the first item in pList and makes the first item the current item.
// Returns NULL and sets current item to NULL if list is empty.
void* List_first(List* pList);
// Returns a pointer to the last item in pList and makes the last item the current item.
// Returns NULL and sets current item to NULL if list is empty.
void* List_last(List* pList);
// Advances pList's current item by one, and returns a pointer to the new current item.
// If this operation advances the current item beyond the end of the pList, a NULL pointer
// is returned and the current item is set to be beyond end of pList.
void* List_next(List* pList);
// Backs up pList's current item by one, and returns a pointer to the new current item.
// If this operation backs up the current item beyond the start of the pList, a NULL pointer
// is returned and the current item is set to be before the start of pList.
void* List_prev(List* pList);
// Returns a pointer to the current item in pList.
// Returns NULL if current is before the start of the pList, or after the end of the pList.
void* List_curr(List* pList);
// Adds the new item to pList directly after the current item, and makes item the current item.
// If the current pointer is before the start of the pList, the item is added at the start. If
// the current pointer is beyond the end of the pList, the item is added at the end.
// Returns 0 on success, -1 on failure.
int List_add(List* pList, void* pItem);
// Adds item to pList directly before the current item, and makes the new item the current one.
// If the current pointer is before the start of the pList, the item is added at the start.
// If the current pointer is beyond the end of the pList, the item is added at the end.
// Returns 0 on success, -1 on failure.
int List_insert(List* pList, void* pItem);
// Adds item to the end of pList, and makes the new item the current one.
// Returns 0 on success, -1 on failure.
int List_append(List* pList, void* pItem);
// Adds item to the front of pList, and makes the new item the current one.
// Returns 0 on success, -1 on failure.
int List_prepend(List* pList, void* pItem);
// Return current item and take it out of pList. Make the next item the current one.
// If the current pointer is before the start of the pList, or beyond the end of the pList,
// then do not change the pList and return NULL.
void* List_remove(List* pList);
// Adds pList2 to the end of pList1. The current pointer is set to the current pointer of pList1.
// pList2 no longer exists after the operation; its head is available
// for future operations.
void List_concat(List* pList1, List* pList2);
// Delete pList. pItemFreeFn is a pointer to a routine that frees an item.
// It should be invoked (within List_free) as: (*pItemFreeFn)(itemToBeFreedFromNode);
// pList and all its nodes no longer exists after the operation; its head and nodes are
// available for future operations.
// UPDATED: Changed function pointer type, May 19
typedef void (*FREE_FN)(void* pItem);
void List_free(List* pList, FREE_FN pItemFreeFn);
// Return last item and take it out of pList. Make the new last item the current one.
// Return NULL if pList is initially empty.
void* List_trim(List* pList);
// Search pList, starting at the current item, until the end is reached or a match is found.
// In this context, a match is determined by the comparator parameter. This parameter is a
// pointer to a routine that takes as its first argument an item pointer, and as its second
// argument pComparisonArg. Comparator returns 0 if the item and comparisonArg don't match,
// or 1 if they do. Exactly what constitutes a match is up to the implementor of comparator.
//
// If a match is found, the current pointer is left at the matched item and the pointer to
// that item is returned. If no match is found, the current pointer is left beyond the end of
// the list and a NULL pointer is returned.
typedef bool (*COMPARATOR_FN)(void* pItem, void* pComparisonArg);
void* List_search(List* pList, COMPARATOR_FN pComparator, void* pComparisonArg);
#endif