Docstoc

Linked Lists

Document Sample
Linked Lists Powered By Docstoc
					                        Linked Lists
      Source: presentation based on notes written by R.Kay, A. Hill and C.Noble




Lists in general
Lists indexed using pointer arrays

Singly linked lists using array storage

Conventional linked list diagrams

Data structure for a linked list node

Inserting a node in a singly linked list

Deleting a node in a singly linked list

Traversing a list and finding keys

Doubly linked lists
                   Lists in general 1
A list is an ordered sequence of items. Previous examples have used
a one-dimensional array or 'vector' to store a list, each element of
the array typically being a record containing data on an item. For
example the following array, in 'C', could store a list of students and
their marks.

Typedef struct person { char name[21];int mark;} PERSON;
PERSON student[100];
                  Lists in general 2

The order of items stored in a list using an array is determined
by the sequential positioning of the items in memory, ie
consecutive items in the list are stored in consecutive memory
locations.

The use of a static array implies that the list will have a fixed
maximum size determined by the variable declaration. This
means that the maximum size must be determined in advance
and the program written to allow for this even though it may
frequently use only a small portion of the array. Alternatively
space for a dynamic array can be calculated and allocated at
runtime using malloc() before storing the items if the number
of records is already known.
                   Lists in general 3
A more important problem is met when one attempts to add an item
to the list whilst preserving the order of the items. for example, to
add the name BOB to the following list, it is necessary to copy each
array element from student [3] onwards up one position in order to
insert the new record. This problem was met when studying the
Insertion Sort algorithm. A similar problem exists when deleting
records from the list.
Lists indexed using pointer array 1
 If each data element is large then the amount of unused space in
 an array may be considerable, particularly if the array has to be
 large enough to anticipate possible maximum use. Inserting,
 deleting or sorting data elements in the array will require a large
 movement of data which will slow the operation of the
 program. These problems can be alleviated by using 'dynamic
 data structures and storing their locations in an array. The
 problem of determining the maximum size of the pointer array
 is still present but this will be considerably less than than that of
 an array of data structures. Inserting, deleting or sorting data
 elements in the array will now require the movement and
 manipulation of pointers which will be faster.
 Lists indexed using pointer array 2
The data storage to the right of the drawing can more flexibly
be allocated independently per record as needed using the
malloc() function.
  Singly linked lists using array or
           dynamic storage 1


A linked list allows data to be inserted into and
deleted from a list without physically moving any
data. Additionally, if the linked list is implemented
using dynamic data structures the list size can vary
as the program executes.

Each data element or 'node' contains an address
pointer. Consecutive items are not necessarily
stored in order or in consecutive memory locations.
Singly linked
 lists using
 array or
 dynamic
 storage 2

 The 2 top diagrams
 represent the same
 data structure. Neither
 is more efficient.

 Insertion requires
 moving indexes, not
 moving data.
    Singly linked lists using array storage
                         3
The bottom 2 diagrams on the previous slide show a node for Bob
(mark 62) being inserted into the linked list in alphabetical order.

Each node contains the address of the node that follows it in the
list. So the nodes can be stored anywhere in memory. The last node
in the list contains a special address that indicates that there are no
further nodes. This sentinel value could be -1 instead of an array
index, or NULL in place of a pointer.

The advantage of a linked list over an array becomes apparent when
an item is added to the list. Since the physical location of each node
does not determine its logical position in the list, there is no need to
move any data. All that is required is to alter one or more of the
address pointers.
Conventional
 linked list
 diagrams 1
   Conventional linked list diagrams 2




Although the items stored in a linked list are in order, it is only possible
to perform a sequential search of the list. A search must start with the
first node and proceed sequentialy from one node to the next.

If dynamic memory allocation is used, the space occupied by the
deleted node must be freed to avoid a memory leak.
  Data structure for a linked list node
Each cell in a linked list will be a structured object. One (or more) data
members (fields) will contain data, and one member will be a pointer to
another similar structured object.

Thus a structure to store data on a student's name and mark could be
declared using:

typedef struct cell {
  char name[21];        int mark; struct cell *next;
} ITEM;

To create dynamic variables requires the use of a pointer variable to
indicate the position of the first structured object. Two further pointer
variables are required to insert and delete other structured objects in the
list. These are declared as follows:

ITEM *p,*q,*first;
           Creating a new list 1

To create the first structured object function malloc() is
used.

first = (ITEM*)malloc(sizeof(ITEM));
first->next = NULL;

Function malloc() requires an integer parameter, in this
case k, for the number of bytes required, in this case the
size of structure item. The void pointer returned by
malloc() has to be cast to (ITEM*), to make it into a
pointer for the correct type of data. The pointer member
next of structure variable first is assigned the value NULL,
a constant defined in stdio.h as value 0.
          Creating a new list 2

It is often convenient to have a dummy node as the first
item in the list to avoid having to process the first node
separately from the remainder. This dummy node contains
no data.
Inserting a node in a singly linked list 1


 insert(ITEM *p,ITEM *q){
    q->next=p->next;
    p->next=q;
 }
 Before this function is called, the new node must
 exist and the address of the node before the insert
 point must be known. This function is more
 complicated if there is no dummy node at the front
 of the list.
Inserting a node in a singly linked list 2
 When insert() is called, *p is assigned the address
 of the node before the insert position and *q is
 similarly pointed at the node to be inserted.
Inserting a node in a singly linked list 3

                          The next pointer of
                          the new node is
                          assigned the address
                          of the following
                          node.


                          The next pointer on
                          the preceding node
                          is made to point at
                          the new node.
Deleting a node in a singly linked list 1

 delete(ITEM *p){
    ITEM *q;
    q=p->next;
    p->next=q->next;
    free(q);
 }

 The parameter *p points to the node before the
 node to be deleted.
Deleting a node in a singly linked list 2


                            When delete() is called,
                            *p is assigned the
                            address of the node
                            before the delete position
                            and *q is declared as an
                            ITEM pointer.

                            q is assigned the address
                            of the node to be deleted,
                            which is stored in the
                            next pointer of the
                            preceding node.
Deleting a node in a singly linked list 3

                            The next pointer of the
                            node before the one to
                            be deleted is pointed at
                            the node after the one
                            to be deleted.


                            The memory occupied
                            by the node to be
                            deleted is freed for
                            reuse to avoid a
                            memory leak.
            Traversing a linked list



void display(ITEM *p){ /* display all nodes in SLL */
  /* print headings */
  printf("\n%-20s%5s\n","name","mark");
  printf("\n%-20s%5s\n","----","----");
  while (p->next!=(ITEM*) NULL){
     /* loops until last node displayed */
     p=p->next; /* first item doesn't contain data, last does */
     printf("%-20s%5d\n",p->name,p->mark);
  }
}
          Finding keys in a linked list
A similar function is used to traverse a SLL in order to find the address of
a data item. Finding nodes before this target point for insertion while
maintaining a sort order or required for a deletion is left as an exercise for
the student.

ITEM *find(ITEM *p, char *searchkey){
  /* find node in SLL with name same as searchkey */
  while (p->next!=(ITEM*) NULL){
      /* loop until last node displayed */
      p=p->next; /* first item doesn't contain data, last does */
      if(strcmp(p->name,searchkey)==0)
         return p;
         /* return address of node found with same name */
  }
  return (ITEM*) NULL; /* search key not in SLL*/
}
               Doubly linked lists 1
A doubly linked list contains both a forward pointer and a
backward pointer; i.e. it contains the address of the preceding
and the following nodes.

A doubly linked list occupies slightly more storage space, and
it is more complex to add or delete nodes since twice as many
address pointers have to be manipulated. However, it can be
traversed in either direction enabling both the node preceding
and the node following a given node to be located.
         Doubly linked lists 2


A doubly linked list node to store data on a
student's name and mark could be declared using:

struct node {
  char name[21];
  int mark;
  struct node *next, *prev; /* pointers to next
                      and previous nodes */
};
typedef struct node ITEM;
        Doubly linked lists 3

In this diagram, we have a doubly linked list in its
initial state with a single dummy node at the head.
Doubly linked
 list node
 insertion 1



q->next=p->next;
p->next=q;
Doubly linked
 list node
 insertion 2

p=q->next;



q->prev=p->prev;
p->prev=q;
 Doubly linked list node deletion

This is left as an exercise for the student. You are
recommended to use a search function to identify the
address of the node to be deleted and then to pass this
address to the delete function. The previous and next nodes
can be identified using the forward and back pointers on
the node to be deleted. The forward and back pointers
within the node to be deleted need to be assigned to the
previous and next nodes. The node to be deleted then needs
to be freed to avoid leaking memory.

The older HTML version of these notes contains some
drawings to illustrate these actions.

				
DOCUMENT INFO
Shared By:
Categories:
Stats:
views:5
posted:4/20/2011
language:English
pages:28