write list docs, cleanup bintree and input docs
This commit is contained in:
parent
d9d49f58bc
commit
eb0fea1212
|
@ -2,3 +2,5 @@ cmake*
|
|||
.cache
|
||||
build
|
||||
compile_commands.json
|
||||
site/
|
||||
web.sh
|
|
@ -139,7 +139,8 @@ void bintree_init(BinTree *tree, void (*destroy)(void *data))
|
|||
|
||||
### bintree_destroy
|
||||
|
||||
Destroys the nodes inside a tree and calls the deallaction function on the data if one was provided. Does not deallocate the tree itself, that is left to the user
|
||||
Destroys the nodes inside a tree and calls the deallaction function on the data if one was provided. Does not deallocate
|
||||
the tree itself, that is left to the user.
|
||||
|
||||
```c
|
||||
void bintree_destroy(BinTree *tree)
|
||||
|
@ -147,7 +148,7 @@ void bintree_destroy(BinTree *tree)
|
|||
|
||||
### bintree_ins_left
|
||||
|
||||
Creates a new node containing `data` and inserts it as the left child of `node`
|
||||
Creates a new node containing `data` and inserts it as the left child of `node`.
|
||||
|
||||
```c
|
||||
int bintree_ins_left(BinTree *tree, BinTreeNode *node, void *data)
|
||||
|
@ -163,7 +164,7 @@ int bintree_ins_right(BinTree *tree, BinTreeNode *node, void *data)
|
|||
|
||||
### bintree_rem_left
|
||||
|
||||
Removes and deallocates the left child node of `node`. Calls the deallocation function on the data if one was provided
|
||||
Removes and deallocates the left child node of `node`. Calls the deallocation function on the data if one was provided.
|
||||
|
||||
```c
|
||||
void bintree_rem_left(BinTree *tree, BinTreeNode *node)
|
||||
|
@ -171,7 +172,7 @@ void bintree_rem_left(BinTree *tree, BinTreeNode *node)
|
|||
|
||||
### bintree_rem_right
|
||||
|
||||
Removes and deallocates the right child node of `node`. Calls the deallocation function on the data if one was provided
|
||||
Removes and deallocates the right child node of `node`. Calls the deallocation function on the data if one was provided.
|
||||
|
||||
```c
|
||||
void bintree_rem_right(BinTree *tree, BinTreeNode *node)
|
||||
|
@ -179,7 +180,7 @@ void bintree_rem_right(BinTree *tree, BinTreeNode *node)
|
|||
|
||||
### bintree_debug_print
|
||||
|
||||
Prints a representation of the tree to stdout. Gets very messy with large trees
|
||||
Prints a representation of the tree to stdout. Gets very messy with large trees.
|
||||
|
||||
```c
|
||||
void bintree_debug_print(BinTree *tree)
|
||||
|
@ -187,7 +188,7 @@ void bintree_debug_print(BinTree *tree)
|
|||
|
||||
### bintree_is_eob
|
||||
|
||||
Utility macro that checks if the node is the End Of Branch
|
||||
Utility macro that checks if the node is the End Of Branch.
|
||||
|
||||
```c
|
||||
#define bintree_is_eob(node) ((node) == NULL)
|
||||
|
@ -195,7 +196,7 @@ Utility macro that checks if the node is the End Of Branch
|
|||
|
||||
### bintree_is_leaf
|
||||
|
||||
Utility macro that checks if a node has children
|
||||
Utility macro that checks if a node has children.
|
||||
|
||||
```c
|
||||
#define bintree_is_leaf(node) ((node)->left == NULL && (node)->right == NULL)
|
||||
|
|
|
@ -84,5 +84,5 @@ void del_split(char **sp);
|
|||
/* Usage */
|
||||
size_t sp_sz = 0;
|
||||
char **sp = split("Delete Me!", &sp_sz, " ");
|
||||
void del_split(char **sp);
|
||||
void del_split(sp);
|
||||
```
|
||||
|
|
|
@ -1,3 +1,222 @@
|
|||
# lflinkedlist
|
||||
|
||||
Coming soon
|
||||
A dual sided linked list structure. Used as the foundation for many of the structures in `libflint`
|
||||
|
||||
## Usage
|
||||
|
||||
Create the list. The user is responsible for memory management of the `List` struct.
|
||||
|
||||
```c
|
||||
List *list = malloc(sizeof(List));
|
||||
```
|
||||
|
||||
After the tree is created, init it. The second argument on `bintree_init()` is an optional memory freeing function pointer
|
||||
with signature `void (*destroy)(void *data)`. Use `free()` from the stdlib if you are creating the data with `malloc()`.
|
||||
If allocation of your data is more complex, you can pass your own memory deallocation function as long as it fits the
|
||||
signature.
|
||||
|
||||
In this example, we are passing `NULL` because all memory will be stack allocated.
|
||||
|
||||
```c
|
||||
ll_init(list, NULL);
|
||||
int i = 1;
|
||||
int j = 2;
|
||||
int k = 4;
|
||||
```
|
||||
|
||||
Next, insert data into the list. Data can be inserted from either side of a node.
|
||||
|
||||
```c
|
||||
ll_ins_next(list, list->head, (void *) &i);
|
||||
ll_ins_next(list, list->tail, (void *) &j);
|
||||
ll_ins_next(list, list->tail, (void *) &k);
|
||||
/* List is now 1 2 4 */
|
||||
```
|
||||
|
||||
Lists can have a node removed by either targeting the node directly or removing a node pointed to by the head or tail of
|
||||
another node. The user is responsible for the memory management of the data inside the node, which is why a `void*` must
|
||||
be supplied to hold the data. Since in this example our memory is stack allocated, we don't need to worry about freeing
|
||||
the `void*` but one must still be supplied for the function to work.
|
||||
|
||||
```c
|
||||
/* List is 1 2 4 */
|
||||
/* node is the 2nd node in the list with value 2 */
|
||||
ListNode *node = list->head;
|
||||
/* void pointer to the data inside of the node */
|
||||
void *data;
|
||||
ll_remove(list, node, &data);
|
||||
/* List is now 1 4 */
|
||||
|
||||
printf("Removed: %d\n", *((int *) data));
|
||||
/* Prints "2" */
|
||||
```
|
||||
|
||||
Here is an alternative example using `ll_remove_next()` instead of `ll_remove()`
|
||||
```c
|
||||
/* node is the 2nd node in the list with value 2 */
|
||||
ListNode *node = list->head;
|
||||
void *data; /* void pointer to the data inside of the node */
|
||||
ll_remove_next(list, node, &data);
|
||||
/* List is now 1 2 */
|
||||
|
||||
printf("Removed: %d\n", *((int *) data));
|
||||
/* Prints "4" */
|
||||
```
|
||||
|
||||
To destroy the list, first call `ll_destroy()` to free the nodes in the list and optionally run the destroy function
|
||||
against the data stored in the list. Since this example is stack allocated and we passed `NULL` when creating the
|
||||
list, no destroy function is run against the memory in the nodes. The list itself must be deleted with `free()`
|
||||
|
||||
```c
|
||||
ll_destroy(list);
|
||||
free(list);
|
||||
```
|
||||
|
||||
Complete example:
|
||||
|
||||
```c
|
||||
List *list = malloc(sizeof(List));
|
||||
ll_init(list, NULL);
|
||||
|
||||
int i = 1;
|
||||
int j = 2;
|
||||
int k = 4;
|
||||
|
||||
ll_ins_next(list, list->head, (void *) &i);
|
||||
ll_ins_next(list, list->tail, (void *) &j);
|
||||
ll_ins_next(list, list->tail, (void *) &k);
|
||||
|
||||
printf("List: ");
|
||||
print_ll(list);
|
||||
|
||||
void *data;
|
||||
ll_remove_next(list, list->head, &data);
|
||||
|
||||
printf("List: ");
|
||||
print_ll(list);
|
||||
printf("Removed: %d\n", *((int *) data));
|
||||
|
||||
ll_destroy(list);
|
||||
free(list);
|
||||
```
|
||||
|
||||
## Structs
|
||||
|
||||
### List
|
||||
|
||||
Double ended linked list struct
|
||||
|
||||
```c
|
||||
typedef struct {
|
||||
size_t size;
|
||||
void (*destroy)(void *data);
|
||||
int (*match)(const void *a, const void *b);
|
||||
struct ListNode *head;
|
||||
struct ListNode *tail;
|
||||
} List;
|
||||
```
|
||||
|
||||
Members:
|
||||
|
||||
- `size`: How many nodes are in the list
|
||||
- `destroy`: Optional deallocation function for member data. Use `NULL` if data is stack allocated
|
||||
- `match`: Comparison function between data inside two nodes. This is not used by `List` itself, but is used in structures built on top of `List`
|
||||
- `head`: Pointer to the `ListNode` at the head of the list
|
||||
- `tail`: Pointer to the `ListNode` at the tail of the list
|
||||
|
||||
### ListNode
|
||||
|
||||
Node of the list
|
||||
|
||||
```c
|
||||
typedef struct ListNode {
|
||||
void *data;
|
||||
struct ListNode *next;
|
||||
struct ListNode *prev;
|
||||
} ListNode;
|
||||
```
|
||||
|
||||
Members:
|
||||
|
||||
- `data`: void pointer to the member data in the node
|
||||
- `next`: Pointer to the `ListNode` before this node in the list
|
||||
- `prev`: Pointer to the `ListNode` after this node in the list
|
||||
|
||||
## Functions
|
||||
|
||||
### ll_init
|
||||
|
||||
Initalize the list. User is responsible for freeing memory with `ll_destroy()`.
|
||||
|
||||
```c
|
||||
void ll_init(List *list, void (*destroy)(void *data));
|
||||
```
|
||||
|
||||
### ll_destroy
|
||||
|
||||
Destroys the nodes inside a list and calls the deallocation funciton on the data if one was provided. Does not destroy
|
||||
the list itself, that is left up to the user.
|
||||
|
||||
```c
|
||||
void ll_destroy(List *list);
|
||||
```
|
||||
|
||||
### ll_ins_next
|
||||
|
||||
Creates a new node containing `data` and inserts it after `node`.
|
||||
|
||||
```c
|
||||
int ll_ins_next(List *list, ListNode *node, const void *data);
|
||||
```
|
||||
|
||||
### ll_ins_prev
|
||||
|
||||
Creates a new node containing `data` and inserts it before `node`.
|
||||
|
||||
```c
|
||||
int ll_ins_prev(List *list, ListNode *node, const void *data);
|
||||
```
|
||||
|
||||
### ll_remove
|
||||
|
||||
Removes and deallocates the node pointed to by `node`. The user is responsible for managing the contained data's memory,
|
||||
as such the `destroy` function is **not** run by `ll_remove()`
|
||||
|
||||
```c
|
||||
int ll_remove(List *list, ListNode *node, void **data);
|
||||
```
|
||||
|
||||
### ll_remove_next
|
||||
|
||||
Removes and deallocates the node pointed to by `node`'s `tail` pointer. The user is responsible for managing the contained data's memory,
|
||||
as such the `destroy` function is **not** run by `ll_remove_next()`
|
||||
|
||||
```c
|
||||
int ll_remove_next(List *list, ListNode *node, void **data);
|
||||
```
|
||||
|
||||
### ll_remove_prev
|
||||
|
||||
Removes and deallocates the node pointed to by `node`'s `head` pointer. The user is responsible for managing the contained data's memory,
|
||||
as such the `destroy` function is **not** run by `ll_remove_prev()`
|
||||
|
||||
```c
|
||||
int ll_remove_prev(List *list, ListNode *node, void **data);
|
||||
```
|
||||
|
||||
## Macros
|
||||
|
||||
### LL_ITER
|
||||
|
||||
A utility macro that helps with iterating over an entire list. A `ListNode` pointer named `node` is created as part of
|
||||
this macro and can be used to access the current node in the iteration, so be careful your own variable naming if you
|
||||
intend to use `LL_ITER`.
|
||||
|
||||
```c
|
||||
#define LL_ITER(list) for(ListNode *node = (list)->head; node != NULL; node = node->next)
|
||||
|
||||
/* Example with list of strings */
|
||||
for LL_ITER(list) {
|
||||
printf("%s\n", (char *)(node->data));
|
||||
}
|
||||
```
|
Loading…
Reference in New Issue