Personal tools
You are here: Home Classes Fall 2004 - Spring 2005 CS 151 Lecture 5 -- Linked Lists
Navigation
Log in


Forgot your password?
« May 2008 »
Su Mo Tu We Th Fr Sa
123
456789 10
11121314151617
18192021222324
25262728293031
 
Document Actions

Lecture 5 -- Linked Lists

by admin last modified 2005-05-11 18:13

Linked Lists

Consider the array implementation of List.  It provides efficient access to individual data items by index; in particular, the get and set methods are fast.  However, it has some shortcomings:
  • The resize operation is expensive (in execution time).
  • Adding at the beginning or middle of the list is expensive.
  • Removing from the beginning or middle of the list is expensive.
These characteristics are due to the fact that an array is stored in a contiguous block of memory.  Computer memories are random-access ; that is, any item stored in memory can be retrieved by giving its address.  At the hardware level, addresses are integers from 0 up to the size of the memory.  Arrays are mapped into a contiguous block of addresses in the physical memory.  It is this random access property that makes array access by index a fast operation. 

On the other hand, it is the contiguous nature of the array that is responsible for its drawbacks.  An alternative is the linked list.  A linked list is comprised of a series of memory blocks called nodes.  Each node contains one data item along with a reference ("link") to the next node in the list, as shown below:

 

Some properties of linked lists:
  • Items need not be stored contiguously.  The logical order of the list may not be the same as its physical order.
  • To maintain a logical ordering, each item has a reference to the next item.
  • Items may be removed from the list by skipping over them in the link path.
  • Items may be added to the list by linking them in; that is, modifying a few of the links.
  • Sequential traversal (in logical order) can be performed by following the link path.
For example, we can traverse a linked list, starting with its head node, in a loop:
for(ListNode n = head; n!=null; n=n.next)
    System.out.println(n.datum);

Linked lists are used frequently in the implementation of abstract data types.  Most data structure implementations are either array-based or link-based.

Several variations on the basic linked list are possible, such as
  • Maintaining both a head and tail pointer.
  • Using a sentinel node (dummy node) at the head or tail of the list.
  • Circular linked list.
  • Doubly-linked list.
To illustrate, let's see how we could use a linked list to implement the List interface:



/*
    Linked List implementation.  This implementation uses a nested ListNode class.
    Each ListNode contains one data item and a link to the next node in the
    list.  The LinkedList class itself contains references to the head node and
    the tail node in the list.  It also keeps a count of the number of items in
    the list.
*/

public class LinkedList implements SimpleList
{
    private int nitems;
    private ListNode head,tail;

    private class ListNode {
        private Object datum;
        private ListNode next;

        ListNode(Object datum){
            this.datum = datum;
            next = null;
        }

        ListNode(Object datum, ListNode next){
            this.datum = datum;
            this.next = next;
        }

        private Object getDatum(){
            return datum;
        }

        private ListNode getNext(){
            return next;
        }
    }


LinkedList()
{
    nitems = 0;
    head = null;
    tail = null;
}

private ListNode getnth(int index)
{
    ListNode target = head;

    if(index<0 || index>=nitems)
        throw new IndexOutOfBoundsException();
    for(int k=0; k<index; k++)
        target = target.next;
    return target;
}

public void clear()
{
    nitems=0;
    head=tail=null;
}

public int size()
{
    return nitems;
}

public boolean isEmpty()
{
    return head==null;
}

public Object get(int index)
{
    return getnth(index).datum;
}

public Object set(int index, Object obj)
{
    ListNode node = getnth(index);
    Object temp = node.datum;
    node.datum = obj;
    return temp;
}

public boolean add(Object item)
{
    if(isEmpty())
        head = tail = new ListNode(item);
    else {
        tail = tail.next = new ListNode(item);
    }
    nitems++;
    return true;
}

public Object remove(int index)
{
    Object target;

    if(index<0 || index>=nitems)
        throw new IndexOutOfBoundsException();
    else if(index==0){
        target = head.datum;
        head = head.next;
        if(nitems==1)
            tail = null;
        }
    else {
        ListNode prior = getnth(index-1);
        target = prior.next.datum;
        prior.next = prior.next.next;
        if(nitems==index+1)
            tail = prior;
        }
    --nitems;
    return target;
}

public void add(int index, Object item)
{
    if(index<0 || index>nitems)
        throw new IndexOutOfBoundsException();
    else if(index==nitems)
        add(item);
    else if(index==0)
        head = new ListNode(item, head);
    else {
        ListNode prior = getnth(index-1);
        prior.next = new ListNode(item,prior.next);
        ++nitems;
        }
}

public String toString()
{
    String result = "[";
    for(ListNode n = head; n!=null; n=n.next){
        result += n.datum;
        if(n!=tail)
            result += ",";
    }
    return result+"]";
}

public Iterator iterator() {
    return new Iterator() {
        ListNode cursor = head;
        boolean hasNext(){
            return cursor!=null;
        }
        Object next() {
            Object result = cursor.datum;
            cursor = cursor.next;
            return result;
        }
    };
}



}



Some advantages of linked lists:
  1. Access by pointer is faster than array indexing.
  2. Add and remove don't require shuffling data.
  3. They use only needed storage.
  4. Efficient operations:  adding or removing the first element; appending one list to another.
Some disadvantages:
  1. Process in forward order only (unless doubly-linked).
  2. Extra storage required for links.
  3. Inefficient operations:  access to the nth element.



 

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: