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:
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.
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?
Inserting at the head of a LinkedList
If you move the head reference before you've set another reference to refer to the first node in the list you lose the entire list.
Not if you keep a tail reference. If you keep a tail reference, you need to test whether head == null. If so, set
The algorithm is O(1). It requires the same number of operations regardless of the size of the current list.
The general algorithm for searching a linked lists is as follows:
current = head
Does this algorithm handle the case when the target is not found?
What is the running time of the algorithm?
//a constant time operation
//if the list is empty, do nothing
Notice that the delete tail operation iterates through the entire list. This requires visiting n nodes, so the operation requires linear time.
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 (
You can then execute the following algorithm:
This is an O(n) operation. As always, make sure to consider special cases!
Arbitrary deletion is a similar operation.
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.
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.