Upload
ophelia-price
View
214
Download
0
Embed Size (px)
Citation preview
Linked Lists
Revision Based on:
http://www.academic.marist.edu/~jzbv/
Linked Lists
• LinkedList is an important data structure in OO languages such as Java and C#
• What you need to learn is how to write the implementation.
• Our philosophical principle: in pursuit of absolute simplicity.
• How: Divide, Conquer, and Glue
What to Do?
• Interface IList is given
• Two implementations are discussed:– Solution One: Doubly Linked List Class– Solution Two: Singly Linked List Class
Interface IList
• Interface IList has the following methods:a. boolean add( Object x) -- append to end of the list
b. boolean add(int i, Object x) – insert at position i
c. boolean remove(int i) – remove object at position i
Linked Lists
A LinkedList implements the interface IList
There are a number of ways in which a LinkedList can be implemented internally, but each implementation should provide the client (code that uses a LinkedList) with a single common set of operations that can be evoked by messages to the LinkedList object.
Types of LinkedList implementations include:
•Doubly linked list
•Singly linked list
We will examine how the main List operations are implemented in each of these alternatives
Linked Lists
Doubly-linked List
A LinkedList is a connected sequence of Nodes. It is composed of two classes of objects: LinkedLists and Nodes.
class Node {
//Node methods go here
//attributes
private Node pred, succ;
private Object data;
}
class LinkedList implements IList {
//class Node (see left) is declared here
//implementation of List methods goes here
//attributes
private Node head, tail;
private int size;
}
Node is an internal class visible only to LinkedList objects.
The private attributes: pred and succ, have class scope and are thus indirectly accessible via the setter/getter methods in class LinkedList. BUT for the illustration purpose, we treat them as protect, which you can set and get a value for them.
Linked Lists
pred succdata pred succdatap
This is the the Node that p points to
This Node is the successor of the Node that p points to
Useful terminology for referring to Nodes in a LinkedList
Nodes are not named objects, but are referred to by a “pointer”
Node p = new Node(theObject);
p.succ = new Node(nextObject);
Linked Lists
LinkedList aList = new LinkedList( );
head size tail
aList
0
aList.add( new Integer(24) );
24
Integer temp = new Integer(24);
Node p = new Node (temp);
p
if (head == 0)
head = p;
tail = p;
size++;
1
aList.add( new Integer(21) );
Integer temp = new Integer(21);
Node p = new Node(temp);
p
21
//head != 0
tail.succ = p;
p.pred = tail;
tail = p;
size++;2
Linked Lists
Putting it together
public boolean add (Object theObj) {
Node p = new Node(theObj);
if (head == 0)
head = p;
else {
tail.succ = p;
p.pred = tail;
}
tail = p;
size++;
return true;
}
Linked ListsInserting an object at position i
aList
head size tail3
10 21 24
Insert at front of the list (i == 0)
Integer temp = new Integer (3);
Node p = new Node(temp);
p
3
p.pred = 0;
p.succ = head;
The successor of Node referenced by p is Node referenced by head
if (head != 0)
head.pred = p;
else (head ==0) -- inserting into an empty list -- set tail = p
head = p;size++;
4
Linked ListsInserting an object at position i
aList
head size tail3
10 21 24
Inserting at end of non-empty list (i==size)
Integer temp = new Integer (3);
Node p = new Node(temp);
41
p
if (i == size) { //insert at end
p.pred = tail;
p’ s predecessor is the Node tail points to
p.succ = 0;
tail.succ = p;
Make Node p points to the successor of Node tail points to
tail = p;
The Node p points to is now at the end of the list
size++;4
Linked ListsInserting an object at position i
aList
head size tail3
10 21 24
Inserting at general position – (0 <= i < size)
Integer temp = new Integer (23);
Node p = new Node(temp);
p
23Move a handle to the Node at position i – Let i = 2 in this example
int count = 0;
Node q = head;
q
count = 0
while (count < i) {
count++;
q = q.getNext( );
}
count = 1
q
count = 2
q
Insert new Node before the Node that q points to.
p.pred = q.getPrev( ));
p.succ = q;
q.getPrev( ).succ = p; //3
q.pred = p; //4
size++;
4
The order of these statements is important – statement 3 MUST precede statement 4.
Linked ListsPutting it all together
public boolean add(int i, Object x) {
if (i < 0 || i > size) { //range error
System.err.println (“error – index out of range”);
System.exit(1); //better – throw Exception
}
Node p = new Node(x);
if (i ==0) { //insert at front
p.pred = 0; //superfluous
p.succ = head;
if (head !=0)
head.pred = p;
else
tail = p;
head = p;
}
else if (i == size) { //insert at end
p.succ = 0;
p.pred = tail;
tail.succ = p;
tail = p;
}
else { //insert at general position
int count = 0;
Node q = head;
while (count < i) {
count++;
q = q.getNext( );
}
p.pred = q.getPrev( );
p.succ = q;
q.getPrev( ).succ = p;
q.pred = p;
}
size++;
return true;}
q.getPrev( ) returns a reference to the previous Node –
Make the successor of that Node = p.
Linked ListsRemoving objects from a List
head size tail
aList
21 24 41
3
Remove first Node – (i == 0)
Node p = head;
if (i ==0) { //remove first Node
head = p.getNext( );
if (head != 0)
head.pred = 0;
else //removing last node
tail = 0;
size--;
}
p
2
Automatic garbage collection reclaims the unreferenced Node when p goes out of scope.
Linked ListsRemoving objects from a List
head size tail
aList
21 24 41
3
Remove the last node – (i == size – 1)
if (i ==size-1) { //remove last Node
p = tail; //Node * p; set previously
if (head != tail) {
tail.getPrev().succ = 0;
tail = tail.getPrev( ); }
else { //removing last node
tail = 0; head = 0; }
size--;
}
p
tail.getPrev( )
2
Automatic garbage collection reclaims memory when p goes out of scope
Linked ListsRemoving objects from a List
head size tail
aList
21 24 41
3
Remove Node in general position – ( i ==1)
Node p = head; int pos = 0;
while (pos < i) { //find node to cut
p = p.getNext( ); //move handle
pos++; }
p.getPrev( ).succ = p.succ;
p.getNext( ).pred = p.pred;
size--;
}
p
pos = 0
p
pos = 1
p.getPrev( ) p.getNext( )
2
The Node referenced by p is deleted when p goes out of scope
Linked ListsBringing it all back home
public boolean remove(int i) {
if (i < 0 || i >= size) { //range error
System.err.println (“error – index out of range”);
System.exit(1);
}
Node p;
if (i == 0 ) // remove first node
p = head;
head = p.succ;
if (head != 0)
head.pred = 0;
else
tail = 0;
} //end if
else if (i == size-1) { //remove last node
p = tail;
if (head != tail) {
tail.getPrev.succ = 0;
tail = tail.getPrev( );
}
else {
head = 0; tail = 0; }
} //end else if
else { //remove Node in general position
p = head;
int pos = 0;
while (pos < i ) { //move handle
p = p.getNext( );
pos++
}
p.getPrev.succ = p.succ;
p.getNext.pred = p.pred;
} //end elsep.setPrev(0); p.setNext(0); //for safetysize--; return true;
} //end remove
Linked Lists
Singly-linked Listspublic class Node {
public Node(Object x) {…}
public void setNext( ) {…}
public Node getNext( ) {…}
public Object getData( ) {…}
private Node succ;
private Object data;
}
size head tail
aList
p p p
3
21 24 47
Move two handles in sequence until p reaches position i – (let i = 2)
Node p = head, q = head;
q
for(int pos = 0; pos < i; pos++) {
q = p; p = p.getNext( ); }
pos = 0
q
pos = 1pos =2
To perform an insert at pos, insert the new Node after the Node that q references and before the Node that p references
To remove the Node at index pos, remove the Node that p references. Use the Node that q references to reattach the links.
Implementing methods add( ) and remove( ) will be left as an exercise.
data succ