Suite101

The Linked List Abstract Data

Defining required data structures and linking strategies for object re-use, maintenance and neutral implementation.

© Guy Lecky-Thompson

Library Cards, SXC.hu
This abstract data type tutorial concentrates on linked lists–defining the required data structures, linking strategies for lists,and how linked lists can be implemented.

Introduction

Abstract data types enable us to create user defined objects that have properties and methods that are distinct from their implementation. It is a concept at the core of object oriented programming allowing for:

  • Object Re-use
  • Ease of maintenance
  • Neutrality of implementation

A linked list is simply a self-organizing storage container. Data of any type may be stored in each node, and each node is connected to at least one other. The two common types are singly and doubly linked lists, which are covered in a later article.

Linked List Data Type

A linked list abstract data type usually has two components. The first is a list management, or container, component. It needs to contain references to the first (and possibly last) node in the list, as well as the node that is currently 'in focus'.

Object : LinkedList
Properties :
Head_Node of type ListNode_Reference

The second component is the data node. Each linked list contains a collection of nodes that are connected together - they refer to each other. Rather than containing a collection of references - one to each node - the list container simply has to contain a reference to the first node, commonly known as the head.

Object : ListNode
Properties :
NextNode of type ListNode_Reference
DataContent of ANY type

Allocating the DataContent will vary from one language to another. The C language, for example, allows the use of a pointer known as void which can be cast into any data type. Most implementations will store DataContent as a reference to another user define object; probably an abstract data type itself.

Linked List Methods

The linked list abstract data type needs methods to set up the container, add, remove and access nodes, as well as ways to traverse the list. This list traversal can take several forms, but the most common is to provide a way to return the reference to the first node, and then follow the chain until the mast node, at which point an end of list value should be returned.

The container needs also to be able to destroy itself, and remove the nodes associated with it. With these methods defined, we need no longer worry about how the node will manage itself, and can concentrate on making use of it.

Object : LinkedList
Properties :
Head_Node
Methods :
GetFirst() returns ListNode or NO_ITEMS
GetNext () returns ListNode or END_OF_LIST
AddNode (ListNode_Reference) returns nothing
DeleteNode() returns ListNode_Reference or END_OF_LIST
DestroyList() returns nothing

One note is that DeleteNode should delete the node currently in focus. AddNode might add the node top the start, end, or insert the node in the case of a sorted linked list. Each node contains methods allowing the node to manage its own properties, including a reference to neck node in the linked list.

Object : ListNode
Properties :
NextNode of type ListNode_Reference
DataContent of ANY type
Methods :
GetNext() returns NextNode
GetData() returns DataContent
SetNext() returns nothing
SetData() returns nothing
DestroyNode() returns nothing

The DestroyNode is described later on, as it is a special case. The other methods should be fairly self-explanatory. It is assumed that when the ListNode is destroyed, it cleans up after itself by releasing its DataContent.

Using The Singly Linked List

Typically, this is a multipart operation. First, we set up an abstract data type, complete with the required functions for it's management, which represents the daya we want to store. Then, we can pass that to the ListNode during a call to SetData.

We can then invoke the creation of a LinkedList container, and use GetFirst to ensure that it is empty. Provided that it is, we can proceed to create a ListNode, set the data with SetData, and add it to the list with a call to AddNode, using a reference to the newly create data object.

Traversing the list requires calls to GetFirst and GetNext, testing the return values appropriately:

if Linkedlist-GetFirst() is not NO_ITEMS then
nbsp;do the following
nbsp; Operations LinkedList-GetCurrent()
nbsp;while LinkedList-GetNext() is not END_OF_LIST

We can also delete the node that is in focus, by first checking that it is the correct one, and then deleting it:

if LinkedList-GetCurrent()-GetData() should be deleted then
LinkedList-DeleteNode();

Finally, we can destroy the list with a simple call to DestroyList. A common way to implement the DestroyList and DestroyNode methods is as a recursive call:

method ListNode::DestroyNode
if this-GetNext() is not END_OF_LIST then
this-GetNext()-DestroyNode();
delete this

Before each node self-destructs, it calls the destruction of the node that follows it. This carries on down the chain until the final node finds no more after itself, and the function returns. This approach is quite heavy on calling stack space, but a better implementation is left as an exercise for the reader.


The copyright of the article The Linked List Abstract Data in Computer Programming is owned by Guy Lecky-Thompson. Permission to republish The Linked List Abstract Data in print or online must be granted by the author in writing.





Post this Article to facebook Add this Article to del.icio.us! Digg this Article furl this Article Add this Article to Reddit Add this Article to Technorati Add this Article to Newsvine Add this Article to Windows Live Add this Article to Yahoo Add this Article to StumbleUpon Add this Article to BlinkLists Add this Article to Spurl Add this Article to Google Add this Article to Ask Add this Article to Squidoo