Next: , Previous: Usage, Up: Usage


2.1 Overview

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.