Next: Data Encapsulation, Previous: Usage, Up: Usage
Functions are available for both singly and doubly linked lists. Certain functions are extremely expensive for singly linked list, but are included for completeness. Those functions which operate on singly linked lists have a prefix of ‘sll_’, those which operate on doubly linked lists one of ‘dll_’. In the discussion which follows, the prefix is specified as ‘?ll’ except in cases where the function is available only for a specific type of list.
This package provides two, parallel, interfaces to lists. The first, preferred, method, is to return results from searches, etc. as node data rather than as references to nodes. This helps shield the user from the vagaries of the list implementation, and, in most cases, is really what the user wants.
The second method deals directly with node handles. This is generally more efficient, but requires more care by the user. It also permits more specialized manipulations, such as moving nodes between lists without the need to create and destroy nodes. It's also the only way to have the user step through the list (there is a method of automatic list traversal with a callback function at each node). The routines which work with node handles generally have the string ‘node’ in their names.
Lists are constructed with ?ll_new
and are destroyed with
?ll_delete
or ?ll_udelete
. While it is possible to insert
data without any intrinsic order (inserting at the head or tail of the
list, for example), it is also possible to insert data according to a
user defined collating sequence. A comparison function to implement
this order is passed to the list creation routines. Note that there is
no consistency check made if the user chooses to mix sorted inserts with
other inserts.
Nodes are created and inserted into lists with ?ll_insert
,
?ll_insert_head
, ?ll_insert_tail
. Detached nodes
(detached with ?ll_detach_node
) may be inserted with
?ll_insert_node
, ?ll_insert_head_node
, and
?ll_insert_tail_node
.
Nodes can be removed from lists either by completely destroying them,
via ?ll_destroy
, ?ll_destroy_head
,
?ll_destroy_tail
, ?ll_destroy_node
, or by detaching them
from the list via ?ll_detach_node
. The latter is useful if a
node is to be moved from one list to another. Detached nodes are
themeselves destroyed with ?ll_destroy_dnode
. Two lists may be
joined efficiently via ?ll_join
.
A list is searched with ?ll_search
, or ?ll_search_node
.
The first returns a pointer to the user data, the last a pointer to the
node.
The head and tail nodes are accessed via ?ll_head
,
?ll_tail
, ?ll_head_node
, and ?ll_tail_node
. The
latter two return handles to the appropriate node.
The list can be traversed and an action performed at each node
traversals via ?ll_traverse
and ?ll_utraverse
. The latter
provides for the passing of extra data to the user provided action
routine. Doubly linked lists can be traversed either from head to tail
or from tail to head.
Once a specific node has been identified via any of the node handle
retrieval routines, various manipulations are possible. It can be
detached from the list (?ll_detach_node
); you can find its
predecessor or successor nodes (?ll_next_node
,
?ll_prev_node
), predecessor or successor data (?ll_next
,
?ll_prev
); its data can be retrieved and modified
(?ll_node_get_data
; and ?ll_node_put_data
); and you can
delete it (?ll_destroy_node
);.
The number of nodes in a list is available via ?ll_count
. The
size of a node is available via ?ll_sizeof_node
.