We use a special node marked as head to reference the first node of the list.
In a singly linked list each node stores data and keeps reference to the next node. First node is referenced by head and last node does not have a next node reference.
[head|o]--->[data1|o]--->[data2|o]--->[data3|o]--->%
I a doubly linked list each node stores data and keeps reference to the previous node and the next node. First node does not have a previous node reference and last node does not have a next node reference.
[head|o]--->[o|data1|o]--->[o|data2|o]--->[o|data3|o]--->% | ^ | ^ | %<----+ +--------+ +---------+
A circular list is similar to singly where each nor keeps reference to the next node adn the last node references the first node as its next node reference. Head points to the first item which can be any item in the list because of the circular nature of the list.
[head|o]--->[data1|o]--->[data2|o]--->[data3|o]---+ ^ | | | +-------------[o|data4]<------------+
Representing linked list
class SNode { object data; SNode next; }; class SNode { object data; SNode next, prev; }; class SList { SNode head; int itemCount; }; class DList { DNode head; int itemCount; };
Insert Operation
We want to insert a node at the front of the listvoid insert(SList list, object data) { SNode node = new SNode(); node.data = data; node.next = list.head; list.head = node; }
Quiz: How would you implement a stack using a linked list
Problem: Implement a doubly linked list
Problem: Implement a circular list
Find operation
Given a data value we need to find the node that stores that data. We the head item to get first item in the list and follow the next reference to find the item with given data or we reach the end of the list.SNode find(SList list, object data) { SNode cur = list.head; while(cur != null && !cur.data.equals(data)) { cur = cur.next; } return cur; }
Delete operation
Let us consider the following list:[head|o]--->[ 5 |o]--->[ 9 |o]--->[ 6 |o]--->[ 13 |o]--->%
[head|o]--->[ 5 |o]--->[ 6 |o]--->[ 13 |o]--->%
[head|o]--->[ 5 |o]--->[ 6 |o]-X->[ 6 |o]--->[ 13 |o]--->% | delete ^ +---------------------+
void delete(SList list, SNode node) { if(node.next != null) { node.data=node.next.data; node.next = node.next.next; } else { SNode cur = list.head; if(cur == node) list.head=null; while(cur.next != node) { cur = cur.next; } cur.next = node.next; } }
Problem: Implement the list that uses a sentinel node to mark end of list and rewrite the delete operation by using sentinel node so that it always completes in constant time.