Linked Lists


Overview

A linked list is a data structure that can store a collection of items. Like arrays, linked lists are used to store several objects of the same type. However, linked lists differ from arrays in the following ways:

Linked lists are typically depicted as follows:

Linked List 2

Each element of the list is referred to as a node. Each node contains an Object that represents the data stored in the node and a reference to the next node in the list. The last node in the list refers to null.

The first node in the list is referred to by a reference head. The last node in the list is optionally referred to by a reference tail.

Implementation Details

To implement a Linked List in Java you must implement 2 classes -- one to represent a Node and one to represent the entire list.

Node

The Node class will have two data members, the Object and the next reference. It should also provide appropriate constructor(s) and get/set methods.

What will be the type of the next reference?

LinkedList

The LinkedList class will maintain appropriate references to the data stored in the list and will provide methods to add data, remove data, and access data.

What are the data members of LinkedList?

Insertion

Inserting at the head of a LinkedList

Linked list 3

  1. Set the next reference of the new node to the node that head refers to
  2. Set the head to refer to the new node

+What would happen if I reordered the previous steps?

+Does this algorithm work for the empty list?

+What is the big-oh running time of the algorithm?

+Inserting at the tail of a LinkedList

Find

The general algorithm for searching a linked lists is as follows:

current = head
//for each item in the list
while(current != null)
	//if the data matches the target
	if(target.equals(current.getData())
		return true
	//advance current
	current = current.getNext()
return false

Does this algorithm handle the case when the target is not found?

What is the running time of the algorithm?

Deletion

+Deletion of head

+Deletion of tail

Arbitrary Insertion/Deletion

To insert in an arbitrary position in a linked list, for example in order to maintain a sorted list, you must find the node that comes before the node you wish to insert (previous) as shown below:

linked list 4

You can then execute the following algorithm:

new_node.setNext(previous.getNext())
previous.setNext(new_node)

This is an O(n) operation. As always, make sure to consider special cases!

Arbitrary deletion is a similar operation.

Doubly Linked Lists

Doubly linked lists, as you might imagine, are linked lists wherein each node maintains a reference to the next node in the list and a reference to the previous node in the list. They have the advantage that you can move forward and backward in the list. So, removing the last node of the list is a constant time operation, not a linear time operation as with singly linked lists. However, maintaining two pointers for each node adds overhead with respect to memory used and maintenance of the references.

linked list 5

Often, doubly linked lists are implemented by using sentinel nodes. In the example above, the nodes header and trailer are dummy nodes that contain irrelevant data. This approach eliminates the need to deal with the empty list as a special case.

You should be able to implement a doubly linked list and provide running time analysis for each of your list operations.


Sami Rollins

Date: 2007-10-01