Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Data Structures & Algorithms Java Collections API & Linked Lists G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 1 Data Structures & Algorithms Java Collections API G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 2 Portion of the Java Collections API (showing list implementations) https://www3.ntu.edu.sg/home/ehchua/programming/java/images/Collection_ListImplementation.png G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 3 extends implements extends AbstractList extends http://www.falkhausen.de/download/diagram/img/java.util.Collection.gif 4 Iterators • Note that the Collection interface specifies that every class implementing this interface must have a method, iterator(), that returns an object of type Iterator – The iterator() method is actually inherited from the Iterable interface • An iterator is simply an object that enables you to step through each item in a collection G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 5 Iterators • In Java, iterators must implement the Iterator interface, which specifies 3 methods: – hasNext() : indicates whether or not there is a “next” item in the collection – next() : retrieves the “next” item – remove() : removes the “next” item http://www.it.iitb.ac.in/~prathabk/pages/proje cts/dp/pattern_info/images/Iterator.jpg 6 3 ways to iterate through a list in Java • Method 1: Using the get(index) method within a loop public static void main(String[] args) { ArrayList<String> listOfNames = new ArrayList<String>(); listOfNames.add("Marc"); listOfNames.add("Kofi"); listOfNames.add("Mansah"); System.out.println(”The names are: "); for (int i=0; i<listOfNames.size(); i++) System.out.println(listOfNames.get(i)); } G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 7 3 ways to iterate through a list in Java • Method 2: Using an iterator and a loop public static void main(String[] args) { ArrayList<String> listOfNames = new ArrayList<String>(); listOfNames.add("Marc"); listOfNames.add("Kofi"); listOfNames.add("Mansah"); System.out.println(”The names are: "); Iterator<String> iter = listOfNames.iterator(); while (iter.hasNext()) System.out.println(iter.next()); } G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 8 3 ways to iterate through a list in Java • Method 3: Using an enhanced for-loop (aka a for-each loop) public static void main(String[] args) { ArrayList<String> listOfNames = new ArrayList<String>(); listOfNames.add("Marc"); listOfNames.add("Kofi"); listOfNames.add("Mansah"); System.out.println(”The names are: "); for (String item : listOfNames) System.out.println(item); } G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 9 Data Structures & Algorithms Linked Lists G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 10 Linked Lists • Linked Data is made up of individual nodes • Each node contains: – Data • E.g. a String, or an Integer, or some other Object – A Link to the next node • A reference to the next node in the list • We have a chain of nodes • We must record/remember the reference to the first head node – The “head/first reference” G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 11 Forming a Linked Chain by Adding to Beginning • Second student arrives, takes – Blank desk top, no link to next chair a desk • First desk placed in room – Address of the first chair given to instructor – Address of (previous) first desk placed on new desk by instructor – Instructor “remembers” address of new desk Forming a Linked Chain by Adding to Beginning • Third desk arrives – New desk gets address of (previous) first desk from instructor – Instructor remembers address of new desk Removing an Item from a Linked Chain Case 1: Removing an item from the beginning Copyright ©2012 by Pearson Education, Inc. All rights reserved Implementing A Linked List public class Node<T> { private T data; private Node<T> next; public Node (T d, Node<T> n) { setData(d); setNext(n); } public void setData(T d) { data = d; } public void setNext(Node<T> n) { data = d; } public T getData() { return data; } public Node<T> getNext() { return next; } } public class LinkedList<T> { private Node<T> head; public LinkedList(){ head = null; } public void add(T d){ Node<T> newN = new Node<T>(d,head); head = newN; } boolean contains(T d){ Node<T> cur = head; while (cur != null) { if (d.equals(cur.getData())) return true; cur = cur.getNext(); } return false; }... 15 Implementing a Linked List • Because the Node class is conceptually “part of” a List, we can make our lives easier by implementing the Node class inside the LinkedList class, as a nested class. public class LinkedList<T> { … <some code omitted> private static class Node<T> { private T data; private Node<T> next; … <some code omitted> } } • When Node is nested inside LinkedList, all its private data will be directly accessible to the LinkedList class, so the LinkedList class will not need to use the set and get methods of the Node class G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 16 Implementing A Linked List public class LinkedList<T> { private Node<T> head; ... public void add(T d){ Node<T> n = new Node(d, head); head = n; } // private nested class private static class Node<T> { private T data; private Node<T> next; boolean contains(T d){ Node<T> cur = head; while (cur != null) { if (d.equals(cur.data)) return true; cur = cur.next; } return false; } Node (T d, Node<T> n){ data = d; next = n; } } public LinkedList(){ head = null; } } 17 Notes on nested classes • The keyword static is necessary in order to define a nested class as opposed to an inner class (to be explained later). public class LinkedList<T> { … <some code omitted> private static class Node<T> { private T data; private Node<T> next; … <some code omitted> } } G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 18 Notes on nested classes • Because we made the nested class private, it is not visible outside the class – no one needs to know that our LinkedList class is implemented using a “helper” Node class. public class LinkedList<T> { … <some code omitted> private static class Node<T> { private T data; private Node<T> next; … <some code omitted> } } G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 19 Notes on nested classes • If we instead make the nested class public, it would be accessible outside the LinkedList class, but any code outside the LinkedList class would need to refer to it as LinkedList.Node public class LinkedList<T> { … <some code omitted> public static class Node<T> { private T data; private Node<T> next; … <some code omitted> } } • E.g.: LinkedList.Node newNode = new LinkedList.Node(null,null) G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 20 Implementing a Linked List • How would you implement size(), a method that returns the number of items in the list? – What would be the runtime of your method? • How would you implement get(int k), a method that returns the data stored at index k of the list? – What would be the runtime of your method? G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 21 Implementing a Linked List • Now that you have implemented size() and get(int k), what’s the runtime of this piece of code? – You can assume myList is a LinkedList containing n items for (int i=0; i<myList.size(); i++) { System.out.println(myList.get(i)); } G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 22 Implementing A Linked List Iterator public class LinkedList<T> { private Node<T> head; // private nested class private static class Node<T> { ... // as defined previously } // private inner class private class MyIterator implements Iterator<T>{ private Node<T> nextNode; public MyIterator(){ nextNode = head; } public boolean hasNext(){ return (nextNode != null); } public T next(){ T data = nextNode.data; nextNode = nextNode.next; return data; } } public LinkedList(){ head = null; } public void add(T d){ Node<T> n = new Node(d, head); head = n; } public Iterator<T> iterator(){ return new MyIterator(); } ... // remaining code omitted } 23 Inner Classes • MyIterator is defined as an inner class inside the LinkedList class. • An inner class is defined like a nested class, but without the static keyword public class LinkedList<T> { … <some code omitted> private class MyIterator implements Iterator<T> { private Node<T> nextNode; … <some code omitted> } } • Like is the case with nested classes, the outer class can access the private data of the inner class • Furthermore, every instance of an inner class is automatically associated with the instance of the outer class that created it. G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 24 Inner Classes public class LinkedList<T> { private Node<T> head; • Like is the case with nested classes, the outer class can access the private data of the inner class • Furthermore, every instance of an inner class is automatically associated with the instance of the outer class that created it. // private inner class private class MyIterator implements Iterator<T>{ private Node<T> nextNode; public MyIterator(){ nextNode = head; } ...// code omitted – Thus, an inner class can refer to the instance variables of the outer class as if they were its own, i.e. without an object reference. This happens in the highlighted code on the right. • The next slide contrasts how we would define an iterator as a nested class with how we define it as an inner class. } public Iterator<T> iterator(){ return new MyIterator(); } } G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 25 Iterator as a Nested vs. Inner Class public class LinkedList<T> { private Node<T> head; public class LinkedList<T> { private Node<T> head; // private nested class private static class MyIterator<T> implements Iterator<T>{ private Node<T> nextNode; // private inner class private class MyIterator implements Iterator<T>{ private Node<T> nextNode; public MyIterator(LinkedList<T> q){ nextNode = q.head; } ... // code omitted } public MyIterator(){ nextNode = head; } ...// code omitted } } public Iterator<T> iterator() { return new MyIterator(this); } public Iterator<T> iterator() { return new MyIterator(); } } If implemented as a nested class, the iterator would need to be given a reference to the LinkedList it is iterating over. This is not necessary when it is implemented as an&inner class. G. Ayorkor Korsah, Ashesi University College, Data Structures Algorithms 26 Linked List Variations head Singly linked list with a reference to the head/ first node 8 4 13 2 head Singly linked list with a reference to the head/ first node and the tail/last node tail 8 4 13 G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 2 27 Linked List Variations header Singly linked list with a sentinel header node 8 4 2 footer header Singly linked list with sentinel header and footer nodes 8 4 2 G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 28 Linked List Variations Doubly linked list with a reference to the head/ first node and the tail/last node first last 9 8 4 2 6 Doubly linked list with sentinel header and footer nodes header footer 9 8 4 2 G. Ayorkor Korsah, Ashesi University College, Data Structures & Algorithms 6 29