Linked Lists

A linked list is a data structure that consists of a group of nodes that represent a sequence. A linked list has several benefits over a conventional array such that the capacity of the list does not need to be pre-allocated and the nodes can be added or removed from the list easily without reallocation or reorganization of the structure.

A linked list has links to the first and last nodes contained within the list; while each node has links to the next and previous nodes within the list. The two node links allow for traversal of the list in either the forward or backward direction. Each node within the list also contains a pointer to the value (application-defined object) for the node.

Any application-defined object can be placed into multiple lists, but there must be a unique NODE object for each of the lists that the application-defined object will be placed within. All of the list manipulation methods are not inherently thread safe therefore it is up to the calling user code to ensure there are no simultaneous accesses to a particular list (i.e. a list cannot be modified while it is being traversed).

Basic Usage

The following code snippet allocates and initializes a linked list.

#include "Kernel/kernel_list.h"

static LIST list;           /* Allocate a linked list */

void APP_Example(void)
{
    LIST_Init(&list);       /* Initialize the list */
}

Each object that is placed into a linked list requires a NODE object. The NODE object provides the links (pointers) to the other nodes within the list. Although the NODE object could be dynamically allocated, for memory constrained applications it can be advantageous to have the NODE as part of the object that is being placed into a list. An example snippet below illustrates how to define an object using a structure that also provides a built-in node.

#include "Kernel/kernel_list.h"

/* A custom application-defined object */
typedef struct MYOBJECT {
    NODE    node;           /* Allocate a node for inserting into the linked list */
    UINT32  x;              /* An example variable */
    UINT32  y;              /* An example variable */
} MYOBJECT;

static MYOBJECT obj1;       /* Allocate example application-specific object instances */
static MYOBJECT obj2;
static MYOBJECT obj3;

void APP_Example(void)
{
    MYOBJECT* obj;


    LIST_AddLast(&list, &obj1.node, &obj1);     /* Insert each of the example objects into the list */
    LIST_AddLast(&list, &obj2.node, &obj2);
    LIST_AddLast(&list, &obj3.node, &obj3);


    /* The list maintains pointers to the first 
    and last objects contained within the list. */

    obj = LIST_First(&list);                    /* Get the first object within the list (pointer to obj1) */
    obj = LIST_Last(&list);                     /* Get the last object within the list (pointer to obj3) */
}

The following image illustrates the structure of the linked list and nodes as created from the code snippet above.

A list can be walked and iterated using a NODE pointer and the LIST_Foreach() macro. The list is searched forwards from first to last and provides a pointer to each node within the list. For each iteration, the application-defined object can be accessed using node->value. The code snippet below iterates and initializes each object within the list.

void APP_Example(void)
{
    NODE* node;
    MYOBJECT* obj;


    LIST_Foreach(node, &list) {     /* Traverse the list */
        obj = node->value;          /* Capture the value contained within the node */

        obj->x = 0;                 /* Access the application-defined object */
        obj->y = 0;
    }
}

API Reference

void LIST_Init(LIST* list)
Initializes a doubly linked list.
PARAMETERS
list A pointer to a caller allocated list to be initialized.
RETURNS
None.
void LIST_InitNode(NODE* node)
Initializes a node for a linked list.
PARAMETERS
node A pointer to a caller allocated node to be initialized.
RETURNS
None.
void LIST_Clear(LIST* list)
Removes all nodes from a linked list.
PARAMETERS
list A pointer to the list to be cleared.
RETURNS
None.
REMARKS
This is an O(1) operation.
Not thread safe.
void LIST_AddFirst(LIST* list, NODE* node, void* value)
Adds a new node containing the given value to the start of a list.
PARAMETERS
list A pointer to the list to receive the node.
node A pointer to a caller allocated node to be added to the list.
value A pointer to the value for the node to be added.
RETURNS
None.
REMARKS
This is an O(1) operation.
Not thread safe.
void LIST_AddLast(LIST* list, NODE* node, void* value)
Adds a new node containing the given value to the end of a list.
PARAMETERS
list A pointer to the list to receive the node.
node A pointer to a caller allocated node to be added to the list.
value A pointer to the value for the node to be added.
RETURNS
None.
REMARKS
This is an O(1) operation.
Not thread safe.
void LIST_AddBefore(LIST* list, NODE* node, NODE* newnode, void* value)
Adds a node into a list before an existing node.
PARAMETERS
list A pointer to the list to receive the node.
node A pointer to the existing node before which to insert the new node.
newnode A pointer to the node to be added to the list.
value A pointer to the value for the node to be added.
RETURNS
None.
REMARKS
This is an O(1) operation.
Not thread safe.
void LIST_AddAfter(LIST* list, NODE* node, NODE* newnode, void* value)
Adds a node into a list after an existing node.
PARAMETERS
list A pointer to the list to receive the node.
node A pointer to the existing node after which to insert the new node.
newnode A pointer to the node to be added to the list.
value A pointer to the value for the node to be added.
RETURNS
None.
REMARKS
This is an O(1) operation.
Not thread safe.
void* LIST_First(LIST* list)
Returns the value of the first node within a list.
PARAMETERS
list A pointer to the list that contains the value to be returned.
RETURNS
A pointer to the value for the first node within the specified list. NULL if the list is empty.
REMARKS
This is an O(1) operation.
Not thread safe.
void* LIST_Last(LIST* list)
Returns the value of the last node within a list.
PARAMETERS
list A pointer to the list that contains the value to be returned.
RETURNS
A pointer to the value for the last node within the specified list. NULL if the list is empty.
REMARKS
This is an O(1) operation.
Not thread safe.
NODE* LIST_Node(LIST* list, UINT32 idx)
Returns the node at the specified zero-based position index.
PARAMETERS
list A pointer to the list to be searched for the given index.
idx The zero-based position index of the node to be returned.
RETURNS
A pointer to the node at the specified index, if found; otherwise NULL.
REMARKS
The list is searched forwards from first to last.
This performs a linear search and therefore is an O(n) operation where n is the index.
Not thread safe.
void* LIST_Value(LIST* list, UINT32 idx)
Returns the value of the node at the specified zero-based position index.
PARAMETERS
list A pointer to the list to be searched for the given index.
idx The zero-based position index of the value to be returned.
RETURNS
A pointer to the value at the specified index, if found; otherwise NULL.
REMARKS
The list is searched forwards from first to last.
This performs a linear search and therefore is an O(n) operation where n is the index.
Not thread safe.
NODE* LIST_RemoveFirst(LIST* list)
Removes and returns the first node from a linked list.
PARAMETERS
list A pointer to the list that contains the node to be removed.
RETURNS
A pointer to the node that was removed from the list. NULL if the list did not contain any items.
REMARKS
This is an O(1) operation.
Not thread safe.
NODE* LIST_RemoveLast(LIST* list)
Removes and returns the last node from a linked list.
PARAMETERS
list A pointer to the list that contains the node to be removed.
RETURNS
A pointer to the node that was removed from the list. NULL if the list did not contain any items.
REMARKS
This is an O(1) operation.
Not thread safe.
void LIST_Remove(LIST* list, NODE* node)
Removes a node from a linked list.
PARAMETERS
list A pointer to the list that contains the node to be removed.
node A pointer to the node to be removed from the list.
RETURNS
None.
REMARKS
This is an O(1) operation.
Not thread safe.
UINT32 LIST_Count(LIST* list)
Returns the total number of nodes currently contained within a list.
PARAMETERS
list A pointer to the target list.
RETURNS
The current number of nodes contained within the specified list.
REMARKS
This is an O(1) operation.
Not thread safe.
BOOLEAN LIST_Contains(LIST* list, void* value)
Determines whether a value is in a list.
PARAMETERS
list A pointer to the list to be searched for the given value.
value A pointer to the value to locate within the list.
RETURNS
TRUE if the value is found within the list; otherwise FALSE.
REMARKS
This performs a linear search and therefore is an O(n) operation where n is the count of the list.
Not thread safe.
BOOLEAN LIST_ContainsNode(LIST* list, NODE* node)
Determines whether a node is in a list.
PARAMETERS
list A pointer to the list to be searched for the node.
node A pointer to the target node.
RETURNS
TRUE if the node was found within the list; otherwise FALSE.
REMARKS
This is an O(1) operation.
Not thread safe.
NODE* LIST_FindFirst(LIST* list, void* value)
Finds the first node that contains the specified value.
PARAMETERS
list A pointer to the list to be searched for the given value.
value A pointer to the value to locate within the list.
RETURNS
A pointer to the first node that contained the specified value, if found; otherwise NULL.
REMARKS
The list is searched forwards from first to last.
This performs a linear search and therefore is an O(n) operation where n is the count of the list.
Not thread safe.
NODE* LIST_FindLast(LIST* list, void* value)
Finds the last node that contains the specified value.
PARAMETERS
list A pointer to the list to be searched for the given value.
value A pointer to the value to locate within the list.
RETURNS
A pointer to the last node that contained the specified value, if found; otherwise NULL.
REMARKS
The list is searched backwards from last to first.
This performs a linear search and therefore is an O(n) operation where n is the count of the list.
Not thread safe.