CSC 143 Java Linked Lists.

Slides:



Advertisements
Similar presentations
Chapter 22 Implementing lists: linked implementations.
Advertisements

Singly linked lists Doubly linked lists
Stacks, Queues, and Deques. 2 A stack is a last in, first out (LIFO) data structure Items are removed from a stack in the reverse order from the way they.
CSE 143 Lecture 22: Advanced List Implementation (ADTs; interfaces; abstract classes; inner classes; generics; iterators)
Stacks, Queues, and Deques
Stacks, Queues, and Deques
(c) University of Washingtonhashing-1 CSC 143 Java Hashing Set Implementation via Hashing.
Implementing Stacks Ellen Walker CPSC 201 Data Structures Hiram College.
1 Joe Meehean.  Conceptual Picture N items chained together using pointers pointed to by head variable  Advantage allows list to grow indefinitely without.
Arrays and Linked Lists "All the kids who did great in high school writing pong games in BASIC for their Apple II would get to college, take CompSci 101,
Lists Ellen Walker CPSC 201 Data Structures Hiram College.
CSE 143 Lecture 6 Linked Lists slides created by Ethan Apter
Linked Lists Ellen Walker CPSC 201 Data Structures Hiram College.
(c) University of Washington15-1 CSC 143 Java List Implementation via Arrays Reading: 13.
CSE 143 Lecture 24 Advanced collection classes (ADTs; abstract classes; inner classes; generics; iterators) read 11.1, 9.6, , slides.
(c) University of Washington16-1 CSC 143 Java Linked Lists Reading: Ch. 20.
(c) University of Washington16-1 CSC 143 Java Lists via Links Reading: Ch. 23.
Winter 2006CISC121 - Prof. McLeod1 Stuff Deadline for assn 3 extended to Monday, the 13 th. Please note that the testing class for assn 3 has changed.
Chapter 5 Linked Lists II
Linked Bag Chapter 3.
Copyright © 0 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Starting Out with Java From Control Structures through Data Structures by Tony.
M180: Data Structures & Algorithms in Java Linked Lists Arab Open University 1.
List Interface and Linked List Mrs. Furman March 25, 2010.
IMPLEMENTING ARRAYLIST COMP 103. RECAP  Comparator and Comparable  Brief look at Exceptions TODAY  Abstract Classes - but note that the details are.
Data Structures Doubly and Circular Lists Lecture 07: Linked Lists
©The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Chapter Chapter 18 List ADT Animated Version.
“The desire for safety stands against every great and noble enterprise.” – Tacitus Thought for the Day.
CSE 501N Fall ‘09 10: Introduction to Collections and Linked Lists 29 September 2009 Nick Leidenfrost.
1 Chapter 4 Unordered List. 2 Learning Objectives ● Describe the properties of an unordered list. ● Study sequential search and analyze its worst- case.
An Array-Based Implementation of the ADT List
Lecture 6 of Computer Science II
Lists Rem Collier Room A1.02
CSE 373 Implementing a Stack/Queue as a Linked List
Building Java Programs
Programming Abstractions
slides created by Marty Stepp
Top Ten Words that Almost Rhyme with “Peas”
Prof. Neary Adapted from slides by Dr. Katherine Gibson
Topic 11 Linked Lists -Joel Spolsky
Stacks, Queues, and Deques
Building Java Programs
Building Java Programs
CSE 143 Lecture 27: Advanced List Implementation
Lecture 26: Advanced List Implementation
[Chapter 4; Chapter 6, pp ] CSC 143 Linked Lists [Chapter 4; Chapter 6, pp ]
Programming Abstractions
Programming II (CS300) Chapter 07: Linked Lists and Iterators
slides adapted from Marty Stepp and Hélène Martin
slides created by Marty Stepp and Hélène Martin
Building Java Programs
Building Java Programs
List Implementation via Arrays
Building Java Programs
Lists.
slides created by Marty Stepp
slides adapted from Marty Stepp
Building Java Programs
Programming II (CS300) Chapter 07: Linked Lists
Stacks, Queues, and Deques
Lecture 7: Linked List Basics reading: 16.2
slides adapted from Marty Stepp
TCSS 143, Autumn 2004 Lecture Notes
slides created by Marty Stepp
Linked Lists and Loops based on slides by Ethan Apter
CSE 143 Lecture 21 Advanced List Implementation
slides created by Ethan Apter
slides created by Marty Stepp
Topic 11 Linked Lists -Joel Spolsky
slides created by Marty Stepp
slides created by Marty Stepp and Hélène Martin
Presentation transcript:

CSC 143 Java Linked Lists

Review: List Implementations The external interface is already defined Implementation goal: implement methods “efficiently” ArrayList approach: use an array with extra space internally ArrayList efficiency Iterating, indexing (get & set) is fast Typically a one-liner Adding at end is fast, except when we have to grow Adding or removing in the middle is slow: requires sliding all later elements

A Different Strategy: Linked Lists Instead of packing all elements together in an array, create a linked chain of all the elements Draw a picture of the client's view of a 3-element List, the ArrayList-based internal view, and the new LinkedList-based internal view. This is to ensure that the students see that different internal representations can all present the same illusion to the outside cleints -- abstraction!

Nodes For each element in the list, create a Node object Each Node points to the data item (element) at that position, and also points to the next Node in the chain Node next item E Node next item Draw a picture of the client's view of a 3-element List, the ArrayList-based internal view, and the new LinkedList-based internal view. This is to ensure that the students see that different internal representations can all present the same illusion to the outside cleints -- abstraction!

Linked Nodes Each node knows where to find the next node No limit on how many can be linked! A null reference signals the end E E E E Node next item Node next item Node next item Node Draw a picture of the client's view of a 3-element List, the ArrayList-based internal view, and the new LinkedList-based internal view. This is to ensure that the students see that different internal representations can all present the same illusion to the outside cleints -- abstraction! item next null

Linked List The List has a reference to the first Node Altogether, the list involves 3 different object types (List, Node and E) Node next item E null List first Draw a picture of the client's view of a 3-element List, the ArrayList-based internal view, and the new LinkedList-based internal view. This is to ensure that the students see that different internal representations can all present the same illusion to the outside cleints -- abstraction!

Node Class: Data /** Node for a simple list (defined within the LinkedList class who knows about the E type) */ public class Node { public E item; // data associated with this node public Node next; // next Node, or null if no next node //no more instance variables //but maybe some methods } //end Node Note 1: This class does NOT represent the list, only one node of a list Note 2: “public” violates normal practice – but OK if as an inner class (see class example) Note 3: The nodes are NOT part of the data. The data is totally unaware that it is part of a list.

Node Constructor /** Node for a simple list */ public class Node { public E item; // data associated with this node public Node next; // next node, or null if none /** Construct new node with given data item and next node (or null if none) */ public Node( E item, Node next) { this.item = item; this.next = next; } … Node next item

LinkedList Data /** Simple version of LinkedList for CSC143 lecture example */ public class MyLinkedList<E> implements List<E> { // instance variables private Node first; // first node in the list, or null if list is empty … } MyLinkedList first

LinkedList Data & Constructor /** Simple version of LinkedList for CSE143 lecture example */ public class MyLinkedList<E> implements List<E> { // instance variables private Node first; // first node in the list, or null if list is empty … // construct new empty list public MyLinkedList( ) { this.first = null; // no nodes yet (statement is not needed since // null is the default initialization value) }

List Interface (review) Operations to implement: int size( ) boolean isEmpty( ) boolean add( E o) boolean addAll( Collection<E> other) void clear( ) E get( int pos) boolean set( int pos, E o) int indexOf( Object o) boolean contains( Object o) E remove( int pos) boolean remove(Object o) boolean add( int pos, E o) Iterator iterator( ) What don't we see anywhere here?? (No nodes anywhere) Notice: no Nodes!

Method add (First Try) public boolean add( E o) { // create new node and place at end of list: Node newNode = new Node(o, null); // find last node in existing chain: it's the one whose next node is null: Node p = this.first; while (p.next != null) { p = p.next; } // found last node; now add the new node after it: p.next = newNode; return true; // we changed the list => return true Draw picture

Vertices of a triangle Client code: MyLinkedList<Point2D> vertices = new MyLinkedList<Point2D>(); Point2D p1 = new Point2D.Double(100.0, 50.0); Point2D p2 = new Point2D.Double( 250, 310); Point2D p3 = new Point2D.Double(90, 350.0); vertices.add(p1); vertices.add(p2); vertices.add(p3);

Problems with naïve add method Inefficient: requires traversal of entire list to get to the end One loop iteration per link Gets slower as list gets longer Solution?? Buggy: fails when adding first link to an empty list Check the code: where does it fail?

Improvements to naïve add method Inefficient: requires traversal of entire list to get to the end A solution: Remove the constraint that instance variables are fixed. Change LinkedList to keep a pointer to last node as well as the first Buggy: fails when adding first link to an empty list A solution: check for this case and execute special code Q: “Couldn’t we ....?” Answer: “probably”. There are many ways linked lists could be implemented

List Data & Constructor (revised) public class MyLinkedList<E> implements List<E> { // instance variables private Node first; // first link in the list, or null if list is empty private Node last; // last link in the list, or null if list is empty … // construct new empty list public MyLinkedList( ) { this.first = null; // no links yet this.last = null; // no links yet }

Linked List with last MyLinkedList first last E E E E Node next item null Do some examples of how lists get created and updated.

Method add (Final Version) public boolean add( E o) { // create new node to place at end of list: Node newNode = new Node(o, null); // check if adding the first node if (this.first == null) { // we're adding the first node this.first = newNode; } else { // we have some existing nodes; add the new node after the current last node this.last.next = newNode; } // update the last node this.last = newNode; return true; // we changed the list => return true Do some examples of how lists get created and updated.

Method size( ) First try it with this restriction: you can’t add or redefine instance variables Hint: count the number of links in the chain /** Return size of this list */ public int size( ) { int count = 0; return count; } Very slow!

Method size( ) Solution: count the number of links in the list /** Return size of this list */ public int size( ) { int count = 0; for (E e : this) { // use the iterator count ++; } return count; Critique? Very slow! Very slow!

Method size (revised) Add an instance variable to the list class private int numNodes; // number of nodes in this list Add to constructor: numNodes = 0; (though not necessary) Add to method add: numNodes ++; Method size (new version) /** Return size of this list */ public int size( ) { return numNodes; } Critique? Don’t forget to update numNodes whenever the list changes. MyLinkedList first last numNodes Problem: every list operation that adds or removes elements must remember to update the size field. Easy to forget. Need an invariant!

clear Simpler than with arrays or not? /** Clear this list */ public void clear( ) { this.first = null; this.last = null; this.numNodes = 0; } No need to "null out" the elements themselves The garbage collector will automatically reclaim the Node objects

get /** Return object at position pos of this list. 0 <= pos < size, else IndexOOBExn */ public E get( int pos) { if (pos < 0 || pos >= this.numNodes) { throw new IndexOutOfBoundsException( ); } // search for pos'th link Node p = this.first; for ( int k = 0; k < pos; k++) { p = p.next; // found it; now return the element in this link return p.item; Critique? Much slower than array implementation. Avoid linked lists if this happens a lot DO try this at home. Discuss constant-time array version vs. scanning required in this version; don't use LinkedLists if this happens a lot!

add and remove at given position Observation: to add a link at position k, we need to change the next pointer of the link at position k-1 Observation: to remove a link at position k, we need to change the next pointer of the link at position k-1

Helper for add and remove Possible helper method: get link given its position // Return the node at position pos // precondition (unchecked): 0 <= pos < size private Node getNodeAtPos( int pos) { Node p = this.first; for ( int k = 0; k < pos; k++) { p = p.next; } return p; Use this in get, too How is this different from the get( pos) method of the List? It returns the Node and not the item.

remove(pos): Study at Home! /** Remove the object at position pos from this list. 0 <= pos < size, else IndexOOBExn */ public E remove( int pos) { if (pos < 0 || pos >= this.numNodes) { throw new IndexOutOfBoundsException( ); } E removedElem; if (pos == 0) { removedElem = this.first.item; // remember removed item, to return it this.first = this.first.next; // remove first node if (this.first == null) { this.last = null; } // update last, if needed } else { Node prev = getNodeAtPos(pos-1); // find node before one to remove removedElem = prev.next.item; // remember removed item, to return it prev.next = prev.next.next; // splice out node to remove if (prev.next == null) { this.last = prev; } // update last, if needed } this.numNodes --; // remember to decrement the size! return removedElem;

add(pos): Study at Home! /** Add object o at position pos in this list. 0 <= pos <= size, else IndexOOBExn */ public boolean add( int pos, E o) { if (pos < 0 || pos >= this.numNodes) { throw new IndexOutOfBoundsException( ); } if (pos == 0) { this.first = new Node(o, this.first); // insert new link at the front of the chain if (this.last == null) { this.last = this.first; } // update last, if needed } else { Node prev = getNodeAtPos(pos-1); // find link before one to insert prev.next = new Node(o, prev.next); // splice in new link between prev & prev.next if (this.last == prev) { this.last = prev.next; } // update last, if needed } this.numNodes ++; // remember to increment the size! return true;

Implementing iterator( ) To implement an iterator, could do the same thing as with MyArrayList: return an instance of MyListIterator Recall: MyListIterator tracks the List and the position (index) of the next item to return How efficient is this for LinkedLists? Can we do better? Do an interactive example developing an iterator that works faster for linked lists than the default one used for arrays. Needs to keep track of the current *node*, not just the current *pos*. Fortunately, nodes and their next field are public, so we don't have to worry about inner classes etc. to implement this.

Summary MyLinkedList presents same illusion to its clients as SimpleArrayList Key implementation ideas: a chain of links Different efficiency trade-offs than MyArrayList must search to find positions, but can easily insert & remove without growing or sliding get, set a lot slower add, remove faster (particularly at the front): no sliding required