linked lists - ecology labfaculty.cse.tamu.edu/slupoli/notes/java/javalinkedlist… · web...
TRANSCRIPT
Linked Lists in JavaIn general
dynamic objects (with data inside) linked together created on object (and link) at a time during runtime
The overall structure
Why do we even bother?? We have arrays! what would we have to do if we wanted to insert a value in the middle of an
array?? (pic 1) we have to declare some size for the array, but what if we declared too much??
(too little) (pic 2)
Why are we learning Linked Lists anyway?Inserting a value in an Array Deleting a value in an Array
This is a lot of work!! That’s a lot of work too!!
1
Memory differenceso arrays you have to declare space for, that you might not use!!!o Linked Lists are created one element at a time, saving space, BUT
we have to track links (pointers) for EACH Node deleting a Node adding a Node
Memory usage between Arrays and Linked ListsArray Linked Lists
Advantages of a Linked List? instead of using an array of RECORDS, we want something dynamic
o we must know size we want when using an array, so we may waste space has same value holding features
o use a BASE OBJECT to hold multiple values for one instance will be able to show all values within the BASE OBJECT will be able to delete and add more values and records easily all records are linked together
we will go over ArrayList vs LinkedList later
2
The main Character - Nodes called an “Node” created by a BASE OBJECT, (so NodeS are public) Node(s) carry values just like a public class Node(s) will be linked together by a “link”
Representing the Node in a LLCode Picture Example Block formpublic class Node{
private String name;private int testGrade;Node link;
// constructor// setters/getters
}
Nodename
testGrade*
* is the link
“link” is a value (of a Node type), that can point to other Nodes “link” MUST (you need to make sure) two only values
o null nullo another Node
links can be used to travel to each Node o more later on thiso FYIs (end of notes) Links/References/Pointers Debate
In OUR example, any newly added Node, will be added to the REAR of the Linked List
Linked Lists are dynamic, since we never set the length, we can add Nodes at will
think of a Linked List as a train…
3
Those CRAZY links!!!Linking to a Integer (Incorrect) Linking to a String (Incorrect)
Linking to another Node (Correct) Linking to null (Correct)
Remember, a link only points to another Node (not vise versa)
Supporting Actors and how the all work together
Links (all of type Node) // ex. Node FRONT;FRONT LINK will only point at front Node of linked list (look at “the scene”)
o if there are NO Nodes present, otherwise points to null does not move much (if at all), but there are case where it may need to move LINK has 2 values
o nullo front Node in list
private variableREAR
4
value is only point at REAR Node of linked list (look at “the scene”)o if there are any Nodes present, otherwise points to null
moves A LOT since (in our example) each time a new Node is added, REAR needs to move to the new Node that is placed in the rear of the Linked List
value has 2 valueso nullo rear Node in list
private variableCURSOR the “workhorse” used to “traverse” or travel through the Linked List private variableINSERT will actually become a new Node by the code
INSERT = new Node;
collects data you want to place into the Linked List into a NEW Node then, depending on function, will be inserted into the Linked List private variable linking to Linked List IS IMPORTANT, AND TRICKY!!!
PREVIOUS value used for removing a Node keeps track of Node previous of CURSOR private variable needs to be set to null within first few lines of function it is used in
INSERTname
testGrade
5
Ok, What’s the big picture again?? knowing how the linked list should be set up visually is key
Again, the big (working) picture
notice FRONT points to the front of the list (same for REAR respectfully) last Node points to null all Nodes point to one another (except last)
o only one link per NodeStudent Demonstration (5 students minimum)Scenario 1 (students aligned perfectly) (use floor as NULL)Scenario 2 (students point randomly)Scenario 3 (students move throughout the room, but pointing to one another)
6
Linking and tracking issues (and handling deletion!!) One of the most important features of the linked list is the values if the values are NOT assigned in the correct order, you may lose some of the
linked list, and memory Again think of a Linked List as a train, you could end up losing the train if you
don’t couple correctly Concerns with deleting Nodes
o links, making sure the linked list is always connectedo release of physical memory space back to the computer
otherwise we have a memory leako depends on language
C++, must delete Node Java, has garbage collection
Match the code with the image shown below:
1. FRONT AND REAR == NULL2. FRONT == REAR
A B C
7
The Linked List Class (Code given to you) methods pre-created for you
o in the code I give, not by Java itself (Generic Linked List is pre-created)o this is ONLY A LEARNING TOOL!!!
use a 3 file system described belowo easier to find thingso example given to you!!
Lupoli’s Linked List FilesNode.java Linked_List.java Driver.java
simple file code for all methods(listed below)
main()where instance of LL is createdwhere addition of code is done
Linked_List() // constructorsets all links (FRONT, REAR, PREVIOUS, CURSOR) to nullvoid insert(String name, int score)Insert a new Node onto the Linked List. Has two possible ways of inserting in the Linked List:
at the end or rear of the Linked List (default, on we’ll use) at the beginning (or front) of the Linked List
void printList()displays ALL values, Node by NodeBoolean remove(String target)given a “target” (name) , remove the target Node, but re-links the Linked List back together. The Node that is “deleted” (implicitly) when they go out of scope, “garbage collection”.boolean isEmpty()Checks if Linked List is empty or not.
1 = yes // is empty0 = no // is NOT empty
8
The initialization (the beginning for a linked list) use the code given to help no nodes are present as of yet ALL links are set to null in constructor
The beginning of a new listmain ( )Linked_List one = new Linked_List();
source // constructorLinked_List(){
FRONT = null;REAR = null;PREVIOUS = null;CURSOR = null;
}
// Why are all set to null??the scene
9
Adding our first Node Scenarios (to the end of the list) there are two scenarios (pictured below) that have to be coded differently
o adding to an EMPTY listo adding to a non-empty list
Adding our firstEmpty List Non-empty List
Student demonstrationLets see how this works before we get to the code. Start with the “pictures” above.
1. Empty list (3 students needed)a. show how to add a Node at the endb. show how to add a Node at the beginning (lab work)
2. List with a few items (5 students needed)a. show how to add a Node at the endb. show how to add a Node at the beginning (lab work)
Actual Insertion Code for a Linked Listmain ( )
one.insert(“Jack”, 20); // to empty listone.insert(“Peter”, 80); // to a (now) non-empty list
sourcepublic void insert(String name, int score){
INSERT = new Node();// collect information into INSERT NODEINSERT.setName(name);INSERT.setTestGrade(score);
if(isEmpty()) { FRONT = INSERT; } // first item in Listelse { REAR.link = INSERT; } // else what?? When would this happen??
REAR = INSERT;}
Adding our first Node – Empty List10
remember FRONT and REAR need to be adjusted but no nodes are affected since none were present
Portion of Code for an Empty Listpublic void insert(String name, int score){
INSERT = new Node();// collect information into INSERT NODEINSERT.setName(name);INSERT.setTestGrade(score);
if(isEmpty()) { FRONT = INSERT; } // first item in Listelse { REAR.link = INSERT; } // else what?? When would this happen??
REAR = INSERT;}
Code & Visual Representation of adding to an Empty List
// starting off
1
INSERT = new Node();
2
// collect information into INSERT NODEINSERT.setName(name);INSERT.setTestGrade(score);
11
3
if(isEmpty()) { FRONT = INSERT; }// first item in List
4
REAR = INSERT;
Does the order of when FRONT and REAR assigned matter in this case?? (Draw it out!!)
Looking ahead, draw the steps (one by one) if we were to add ANOTHER Node!! We’ll check in a few minutes!!
Use the code above to see if you can add another node to the list!!
12
Adding our first Node – List already contains Nodes list already has at least one node in it have to worry about REAR and the last node
Portion of Code for an Non-Empty List
public void insert(String name, int score){
INSERT = new Node();// collect information into INSERT NODEINSERT.setName(name);INSERT.setTestGrade(score);
if(isEmpty()) { FRONT = INSERT; } // first item in Listelse { REAR.link = INSERT; } // else what?? When would this happen??
REAR = INSERT;}
Code & Visual Representation of adding to a List1
// Starting off// remember, can be MANY nodes
2
INSERT = new Node();
13
3
// collect information into INSERT NODEINSERT.setName(name);INSERT.setTestGrade(score);
4
else { REAR.link = INSERT; }
5
REAR = INSERT; // could be reversed
Why is FRONT never manipulated in this portion of code??Why would FRONT.link (instead of REAR.link) NOT have worked for a list with more than ONE item??
Displaying our list many versions
o while loop (lab work)o for loop (one I use)
uses the CURSOR!!!
14
Displaying the Listed Listthe main
LINKED_LIST one = new LINKED_LIST();one.insert(“Angela”, 261);one.insert(“Jack”, 20);one.insert(“Peter”, 120);one.insert(“Chris”, 270);one.printList();
the sourcepublic void printList( ){
// good for only a few Nodes in a listif(isEmpty()){System.out.println( "No Nodes to display" );return;}
System.out.println("This list has:");
for(CURSOR = FRONT; CURSOR != null; CURSOR = CURSOR.link){
System.out.println(CURSOR.getName());System.out.println(CURSOR.getTestGrade());
} // could use toString() as well}
Code & Visual Representation of displaying a List
// starting off
15
1 CURSOR = FRONT;
2CURSOR != null;System.out.println(CURSOR.getName());System.out.println(CURSOR.getTestGrade());
3 CURSOR = CURSOR.link
4CURSOR != null;System.out.println(CURSOR.getName());System.out.println(CURSOR.getTestGrade());
5 CURSOR = CURSOR.link
6CURSOR != null;System.out.println(CURSOR.getName());System.out.println(CURSOR.getTestGrade());
7 CURSOR = CURSOR.link
16
8CURSOR != null;System.out.println(CURSOR.getName());System.out.println(CURSOR.getTestGrade());
9CURSOR = CURSOR.link
CURSOR != null;// stop here!!
Now the hard part - Removing “The Target” removal of a node is much more complicated have to make sure all links are NEVER severed have to find the target FIRST!!!
o uses same looping code as the printList() BUT previous follows BEHIND CURSOR
Student demonstration(need 5 students minimum (and me as CURSOR))Let’s see how this works before we get to the code. Start with the “pictures” below.
a. deleting a node from the front (no previous)! Search first before deleting!!!b. deleting a node from the middlec. deleting a node from the end d. deleting the ONLY node in a list (no previous)
The “Big Picture” when Deleting a Node
17
Overall Deletion codethe mainone.remove(“Jack”);the source
public boolean remove(String target){
// 3 possible places that NODES can be removed from in the Linked List// FRONT, MIDDLE, REAR// all 3 condition need to be covered and coded
// use Traversing to find TARGETPREVIOUS = null;
for(CURSOR = FRONT; CURSOR != null; CURSOR = CURSOR.link){
if(target.equals(CURSOR.getName())) // match{ break; } // function will still continue, CURSOR will// mark NODE to be removedelse { PREVIOUS = CURSOR; }// PREVIOUS marks what NODE CURSOR is marking// JUST before CURSOR is about to move to the next NODE
}
if(CURSOR == null) { return false; } // never found a matchelse{
// check each condition FRONT, REAR and MIDDLEif((CURSOR == FRONT) && (CURSOR == REAR))// TARGET node was the first and
ONLY in the list{
FRONT = null;REAR = null;
}// why no need for PREVIOUS??else if(CURSOR == FRONT) // TARGET node was the first //in the list{ FRONT = FRONT.link; } // moves FRONT up one node, why no need for
PREVIOUS??else if (CURSOR == REAR) // TARGET node was the //last in the list{ // will need PREVIOUS for this one
PREVIOUS.link = null; // since this node will become //the last in the list
PREVIOUS = REAR;}else // TARGET node was the middle of the list{ PREVIOUS.link = CURSOR.link; }// will need PREVIOUS also for this one
}CURSOR.link = null;CURSOR = null;PREVIOUS = null;return true;}
18
Deleting Nodes – First/Last (and only) Node (FRONT/REAR) one of the more simple ones no PREVIOUS link needed
Code from example needed to complete this task
if((CURSOR == FRONT) && (CURSOR == REAR)){// TARGET node was the first and ONLY in the list
FRONT = null;REAR = null;
}// why no need for PREVIOUS??
…CURSOR.link = null;CURSOR = null;
Code & Visual Representation of deleting a Node
// start here
1
FRONT = null;REAR = null;CURSOR.link = null;CURSOR = null;
Node losses scope, Java Garbage Collection Cleans up!!
Deleting Nodes – First Node (FRONT) again, one of the more simple ones no PREVIOUS link need
Code from example needed to complete this task
else if(CURSOR == FRONT) // TARGET node was the first in the list{ FRONT = FRONT.link; } // moves FRONT up one node, why no need for
…CURSOR.link = null;CURSOR = null;
19
Code & Visual Representation of deleting a Node
// start here
1 FRONT = FRONT.link;// moves FRONT up one node, why no need for PREVIOUS??
2CURSOR.link = null;
3 CURSOR = null;
20
Deleting Nodes – Last Node (REAR) again, one of the more simple ones PREVIOUS link is used, but not needed (still following CURSOR)
Code from example needed to complete this task
else if (CURSOR == REAR) // TARGET node was the //last in the list{ // will need PREVIOUS for this one
PREVIOUS.link = null; // since this node will become //the last in the listPREVIOUS = REAR;
}
…CURSOR.link = null;CURSOR = null;PREVIOUS = null;
Code & Visual Representation of deleting a Node
// start here
1 PREVIOUS.link = null;
2PREVIOUS = REAR;
21
3 CURSOR.link = null;CURSOR = null;
Deleting Nodes – Middle Node this is the toughest of the group since we have
o more links to worry abouto FRONT and REAR are uselesso need CURSOR and PREVIOUS to help out
CURSOR o does double duty
finds the target we want to delete uses CURSOR’s access to the Node AFTER the deleted Node
PREVIOUSo follow behind CURSOR by one Node
Code from example needed to complete this task
else // TARGET node was the middle of the list{ PREVIOUS.link = CURSOR.link; }// will need PREVIOUS also for this one
}CURSOR.link = null;CURSOR = null;PREVIOUS = null;
Code & Visual Representation of deleting a Node
1 // start here
22
2PREVIOUS.link = CURSOR.link;
notice the EXTENDED link for previous!!
3CURSOR.link = null;CURSOR = null;
4 PREVIOUS = null;
What would happen if the code read this instead??CURSOR = null;CURSOR.link = null;
Garbage Collection - FYI Randomly the garbage collector chases all the references in all the objects to
find all the live objects. Anything that can’t be reached is dead and its space in reclaimed in one fell
swoop. System.gc(); // manually starts garbage collection
Pointers versus References/“Links” There is a constant philosophical battle if Java uses “pointers” even though they
are called “references”o pointers have a bad connotation, as not secure (which Java does not
want!!) both do the same thing Java (in their APIs) use the term pointers read for interesting details: http://javadude.com/articles/passbyvalue.htm
23
Generic Doubly Linked List w/ Dummy Header/Tail more powerful since
o the Node could be of ANYTYPEo throws/catches exceptions
dummy Header/Tail eliminate need for careful removing of head/tail with data so not to lose the links
overall setup the same uses an Iterator to move through nodes of ANYTYPE
o the object ANYTYPE needs to have a complete class profile all code is in your book
Doubly Linked Generic Structurepublic class MyLinkedList<AnyType> implements Iterable<AnyType>{ private int theSize; private int modCount = 0; private Node<AnyType> beginMarker; private Node<AnyType> endMarker;
Generic Node Setup private static class Node<AnyType> { public Node( AnyType d, Node<AnyType> p, Node<AnyType> n ) { data = d; prev = p; next = n; }
public AnyType data; public Node<AnyType> prev; public Node<AnyType> next; }
24
Iterator for a Generic Linked List
private class LinkedListIterator implements java.util.Iterator<AnyType> { private Node<AnyType> current = beginMarker.next; private int expectedModCount = modCount; private boolean okToRemove = false;
public boolean hasNext( ) { return current != endMarker; }
public AnyType next( ) { if( modCount != expectedModCount ) throw new java.util.ConcurrentModificationException( ); if( !hasNext( ) ) throw new java.util.NoSuchElementException( );
AnyType nextItem = current.data; current = current.next; okToRemove = true; return nextItem; }
public void remove( ) { if( modCount != expectedModCount ) throw new java.util.ConcurrentModificationException( ); if( !okToRemove ) throw new IllegalStateException( );
MyLinkedList.this.remove( current.prev ); expectedModCount++; okToRemove = false; } }
25
Driver for a Generic Doubly Linked List
class TestLinkedList{ public static void main( String [ ] args ) { MyLinkedList<Integer> lst = new MyLinkedList<>( );
for( int i = 0; i < 10; i++ ) lst.add( i ); for( int i = 20; i < 30; i++ ) lst.add( 0, i );
lst.remove( 0 ); lst.remove( lst.size( ) - 1 );
System.out.println( lst );
java.util.Iterator<Integer> itr = lst.iterator( ); while( itr.hasNext( ) ) { itr.next( ); itr.remove( ); System.out.println( lst ); } }}
ArrayList vs. LinkedLists, who’s better??action L.L. description A.L. description winnerretrieving an item has to go through each node in
order to get to the node in question O(n/2) on average
uses index number, O(n) A.L.
removing an item has to move to that item, then change up links
deletes items, but rest have to move down a spot
L.L.
inserting an itemmemory overheadrandom access“give me the nth element”best for a queuehint: look at APIs
26
Sources:http://www.necessaryandsufficient.net/category/uncategorized/page/39/Thanks to go Antonio Diaz-Battle for some of the graphics
27