Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/nbulischeck/list.h
Linear Linked List Library
https://github.com/nbulischeck/list.h
c header linked-list
Last synced: 1 day ago
JSON representation
Linear Linked List Library
- Host: GitHub
- URL: https://github.com/nbulischeck/list.h
- Owner: nbulischeck
- License: gpl-3.0
- Created: 2018-02-13T02:34:40.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2024-02-24T00:43:43.000Z (5 months ago)
- Last Synced: 2024-03-19T09:34:27.122Z (4 months ago)
- Topics: c, header, linked-list
- Language: C
- Homepage:
- Size: 37.1 KB
- Stars: 48
- Watchers: 6
- Forks: 41
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Lists
- awesome-c-zh - list.h - 单链和双链表函数的实现。[](https://spdx.org/licenses/GPL-3.0-only.html) (数据结构)
README
# list.h
Implementations for singly-linked and doubly-linked list functions.
## Basic Working Example
```C
#include
#include
#include "list.h"typedef struct node {
int key;
struct node *next;
} node_t;node_t *head = NULL;
int main(){
node_t *item, *tmp;item = malloc(sizeof(node_t));
item->key = 5;
item->next = NULL;
SL_APPEND(head, item);SL_FOREACH(head, item) printf("%d\n", item->key);
SL_FOREACH_SAFE(head, item, tmp){
SL_DELETE(head, item);
free(item);
}return 0;
}
```## Functions Available
**Every function has a doubly-linked list counterpart.** The doubly-linked list
version takes the exact same arguments. They are referred to as `DL_` and the function name. For example, `DL_EMPTY` and `DL_APPEND`.| Function Name | Arg 1 | Arg 2 | Arg 3 | Arg 4 |
| ------------- | ----- | ------ | ----- | ----- |
| SL_EMPTY | head | int | | |
| SL_APPEND | head | node | | |
| SL_PREPEND | head | node | | |
| SL_SORT | head | fn * | | |
| SL_LAST | head | node | | |
| SL_REVERSE | head | | | |
| SL_CONCAT | head | head | | |
| SL_LENGTH | head | int | | |
| SL_FOREACH | head | node | | |
| SL_FOREACH_SAFE | head | node | node | |
| SL_INDEX | head | node | int | |
| SL_SEARCH | head | fn * | query | node |
| SL_DELETE | head | node | | |### SL_APPEND
This function appends a node to the end of a linked list.
Argument 1: The head node of the list
Argument 2: The node to be appended to the list
Call:
```C
SL_APPEND(head, node);
```### SL_PREPEND
This function prepends a node to the start of a linked list.
Argument 1: The head node of the list
Argument 2: The node to be prepended to the list
Call:
```C
SL_PREPEND(head, node);
```### SL_SORT
This function sorts a linked list in O(n log n) time.
Argument 1: The head node of the list
Argument 2: A function pointer to a compare function
Call:
```C
SL_SORT(head, fn *);
```>**Note**: The function pointer must be able to identify if one key is less than or equal to another and return a value accordingly. The check to swap is if the return value of the compare function is less than or equal to zero. For strings, you can use `strcmp()` and for integers you can simply return the difference.
### SL_REVERSE
This function reverses a linked list. For example, `a->b->c->d` becomes `d->c->b->a`.
Argument 1: The head node of the list
Call:
```C
SL_REVERSE(head);
```### SL_CONCAT
This function concatenates two linked lists. For example, list1: `a->b` and list2: `c->d` becomes `a->b->c->d`.
Argument 1: The head node of the first list
Argument 2: The head node of the second list
Call:
```C
SL_CONCAT(head, head);
```### SL_LENGTH
This function stores the length of a linked list in the second argument.
Argument 1: The head node of the list
Argument 2: An integer to store the length of the list
Call:
```C
SL_LENGTH(head, length);
```>**Note**: The second argument **will** be clobbered!
### SL_FOREACH
This function iterates over the length of the list and returns the node at each step. This is helpful when operating on every node in the list (printing the list or altering each node).
Argument 1: The head node of the list
Argument 2: A temporary node to store each intermediary node
Call:
```C
SL_FOREACH(head, node);
```### SL_FOREACH_SAFE
This function iterates over the length of the list and returns the node at each step. This is helpful when operating on every node in the list (printing the list, altering each node, or destroying the list).
Argument 1: The head node of the list
Argument 2: A temporary node to store each intermediary node
Argument 3: A temporary node to safely store the next node
Call:
```C
SL_FOREACH_SAFE(head, node, tmp);
```### SL_INDEX
This function returns a node at the nth position in the list. The list is zero-indexed, so if you ask for the 0th node, you'll get the head.
Argument 1: The head node of the list
Argument 2: A temporary node to store the returned node
Argument 3: An integer index value
Call:
```C
SL_INDEX(head, node, index);
```>**Note**: Check for a proper return value after a function call to SL_INDEX. If your index is out of range, a NULL node will be returned.
### SL_SEARCH
This function searches the list and compares each node to the query using the function pointer argument. If a valid match is found, the matching node is placed in the fourth argument `node`. This is one of the most versatile functions due to the nature of the function pointer. You're given the ability to search for nodes, keys (int, char *, ...), etc. The limit to which you can search the list is your ability to write a proper compare function.
Argument 1: The head node of the list
Argument 2: A function pointer to a compare function
Argument 3: The item you want to query
Argument 4: A temporary node to store the returned node
Call:
```C
SL_SEARCH(head, cmp, query, node);
```>**Note**: Check for a proper return value after a function call to SL_SEARCH. If a node is not found, a NULL node will be returned.
### SL_DELETE
This function removes a node from the linked list. **SL_DELETE only unlinks the node!** The memory **must** be freed to avoid a memory leak.
Argument 1: The head node of the list
Argument 2: The node to be removed
Call:
```C
SL_DELETE(head, node);
```## Recipes
Below are some common use cases for the above functions.
### SL_FOREACH
#### Print an entire list
```C
SL_FOREACH(head, node) printf("%d\n", node->key);
```### SL_FOREACH_SAFE
#### Delete an entire list
See [SL_DELETE](#sl_delete-1).
### SL_SEARCH
#### Search by key
```C
/* For integers */
int cmp(node_t *a, int key){
return a->key - key;
}
SL_SEARCH(head, cmp, 5, node);/* For strings */
int cmp(node_t *a, char *key){
return strcmp(a->key, key);
}
SL_SEARCH(head, cmp, "Hello, world!", node);/* For pointers */
int cmp(node_t *a, void *ptr){
return (a->data.ptr == ptr) ? 0 : 1;
}
SL_SEARCH(head, cmp, ptr, node);
```### SL_DELETE
#### Delete a single node
```C
SL_DELETE(head, node);
free(node);
```#### Delete an entire list
```C
SL_FOREACH_SAFE(head, node, tmp){
SL_DELETE(head, node);
free(node);
}
```