Csci 210: Data Structures Linked Lists
Csci 210: Data Structures Linked Lists
Linked lists
Summary
Today
linked lists
single-linked lists
double-linked lists
circular lists
READING:
GT textbook chapter 3.2. 3.3. 3.4
Arrays vs. Linked Lists
null
Arrays vs. Lists
Arrays
have a pre-determined fixed size
easy access to any element a[i] in constant time
no space overhead
Size = n x sizeof(element)
Linked lists
no fixed size; grow one element at a time
space overhead
each element must store an additional reference
Size = n x sizeof (element) + n x sizeof(reference)
no easy access to i-th element wrt the head of the list
need to hop through all previous elements
The Node class
next
int
/** Node of a singly linked list of integers */
public class Node {
self-referential definition
The Node class
next
int
/** Node of a singly linked list of integers */
public class Node {
private int element;
// we assume elements are ints
private Node next;
/** Creates a node with the given element and next node. */
public Node(Int s, Node n) {
element = s;
next = n;
}
// Modifier methods:
/** Sets the element of this node. */
public void setElement(int newElem) { element = newElem; }
head
null
n
void addFirst(Node n)
head
null
void addFirst(Node n) {
n.setNext(head);
head = n;
size++;
}
Notes
Special cases: works when head is null, i.e. list is empty
Efficiency: O(1) time (i.e. constant time)
Inserting in the middle
v
head
null
v
n
null
Notes
Special cases
does it work when list is empty?
Efficiency: takes O(i) time
constant time per element traversed
unlike arrays, accessing i-th element is not constant time
Remove at head
head head
null
Node removeFirst() {
Node n = head;
head = head.getNext();
n.setNext(null);
return n;
}
Notes:
Special cases
does it work when list is empty?
Nope.
How to fix it?
Efficiency: O(1)
Insert at tail
void addLast(Node n) {
insertAfter (get(size), n);
}
Notes
Special cases
does it work when list is empty?
Nope (first node in insertAfter is null).
How to fix it?
Efficiency: takes O(size) time
Delete at tail
private Node head, tail;
// head and tail nodes of the list
private long size;
// number of nodes in the list
void SLinkedList() {
all methods must update tail
head = tail = null;
size = 0;
}
....
}
Insert at tail
void addLast(Node n) {
Efficiency: O(1)
Remove at tail
What we want: delete the last element and set the new tail
Is that possible?
Remove at tail
What we want: delete the last element and set the new tail
Is that possible?
Remove at tail
set the tail to the node BEFORE the tail
need the node before the tail: O(size)
To remove an element from a list you need the node BEFORE it as well
remove(Node n) {
//link n.before to n.next
}
n.setNext(head);
n.setprev(null);
head.setPrev(n);
head = n;
size++;
}
void addFirst(Node n) {
if (head==null) {
//this is the first element: set both head and tail to it
head = tail = n;
n.setPrev(null); n.setNext(null);
}
else {
n.setNext(head); n.setprev(null);
head.setPrev(n);
head = n;
}
size++;
}
Efficiency: O(1)
Insert at tail
void addLast(Node n) {
tail.setNext(n);
n.setprev(tail);
n.setNect(null);
tail = n;
size++;
}
Special cases?
empty list: tail is null; need to set head too
void addLast(Node n) {
if (tail == null) {
head = tail = n; n.setPrev(null); n.setNext(null);
}
else {
tail.setNext(n); n.setprev(tail); n.setNect(null);
tail = n;
}
size++;
}
Efficiency: O(1)
Doubly-linked lists
Class work: Sketch the following methods for doubly-linked lists, and analyze their efficiency.
Node removeFirst()
Node removeLast()
void remove(Node n)
Node search(int k)
Sentinels
dummyhead dummytail
DLLists with sentinels
dummyhead dummytail
insertFirst(Node n) {
n.setNext(dummyHead.getNext());
dummyHead.getNext().setPrev(n);
dummyHead.setNext(n);
n.setPrev(dummyhead);
dummyhead dummytail
size++;
}
Circular lists
make last node point to the first (instead of null)
class CircularList {
SNode head;
int size;
head
}
if head is null?
if (head ==null) {
n.setNext(n);
head = n;
}
Linked-lists in Java