Presentation is loading. Please wait.

Presentation is loading. Please wait.

LINKED LISTS Linear Linked List. November 1, 2005Linked Lists2 of 48 Linked Lists Like stacks and queues, linked lists are lists of nodes that point to.

Similar presentations


Presentation on theme: "LINKED LISTS Linear Linked List. November 1, 2005Linked Lists2 of 48 Linked Lists Like stacks and queues, linked lists are lists of nodes that point to."— Presentation transcript:

1 LINKED LISTS Linear Linked List

2 November 1, 2005Linked Lists2 of 48 Linked Lists Like stacks and queues, linked lists are lists of nodes that point to elements in the list. Nodes are linked with ‘next node’ reference –nodes are chained together, in order, based on a key Our linked list will be sorted –inserting needs to figure out the correct spot for insertion to maintain key order –data must have some basis it can be sorted on, (i.e., the sort key) and must be able to compare its key’s value with other data’s value

3 November 1, 2005Linked Lists3 of 48 Example: Borrowing from the Library Use a linked list to keep track of things that need to be returned to a library. The list should be able to store books, CDs, videos, and anything else that you might have to return. All items have a date that they need to be returned by, and the list should be sorted based on that date. You should be able to search for items by date, insert items, remove items, and check to see if the list is empty. Items from library will be of type LibraryData –have titles and authors. –we want a list that can store anything that “is a” LibraryData –elements of a sorted list must be comparable, so we need some value that we can compare The Date class –we want to compare Date s –Java provides a class java.util.Date –Date class implements the Comparable interface allowing them to be compared (more on this later)

4 November 1, 2005Linked Lists4 of 48 LibraryData Putting it all Together LibraryData combines Authors, Titles, and Date –Date used to store due date Can use LibraryData to store all items from library in single sorted list –will be able to search list based on Date, and retrieve other information associated with Date Thus, our list will keep all items we have borrowed from library in order of their due dates String _title String _author Date _date getTitle getAuthor getDate …..

5 November 1, 2005Linked Lists5 of 48 The Generic List: Stores Comparable s Generalize the list to work for any object as long as we can compare it with other objects of the same type –should be able to store any kind of object that can make specific comparisons between the same type of object –The object must implement the Comparable interface –The interface specifies compareTo method: taking a Comparable as a parameter –compareTo method returns an int negative if object is less than object being compared 0 if object is equal to object being compared positive if object is greater than object being compared How can a class implementing Comparable compare itself to something else if all it knows about the other object is that it implements the Comparable interface? –Comparable interface is a generic interface; allows us to ensure that we only compare against other instances of LibraryData –LibraryData will implement the compareTo method using its getDate() method to get the due date of objects to compare; the Date also implements Comparable and therefore also defines the compareTo method.

6 November 1, 2005Linked Lists6 of 48 The Generic List (cont.) This allows us to define exactly what it means for two objects to be compared –e.g., LibraryData only cares about Date s for comparison and delegates compareTo to its contained Date –other objects implementing Comparable could do more elaborate comparisons, e.g., shape could compute its area Comparable data stored in list, using generics for the particular type –each item must be an instance of same class implementing Comparable –can polymorphically mix instances of subclasses only if they share a common type of key that can be compared –Comparable classes store a key and are given another Comparable of the same class to compare themselves to

7 November 1, 2005Linked Lists7 of 48 Specific Comparable s The Comparable interface public interface Comparable { public int compareTo(ElementType toCompare); } By using generics we ensure that the parameter is the same type that is implementing the Comparable interface LibraryData implements Comparable ; because of generics we can be assured that parameter in compareTo() is of type LibraryData –Since we know that the parameter is of type LibraryData, can call getDate() on it

8 November 1, 2005Linked Lists8 of 48 Code for class LibraryData public class LibraryData implements Comparable { private java.util.Date _date; private String _title; private String _author; public LibraryData(java.util.Date date, String title, String author) { _date = date; _title = title; _author = author; } public java.util.Date getDate() { return _date; } public String getTitle(){ return _title; }... // LibraryData’s compareTo delegates to // _date’s compareTo public int compareTo(LibraryData toCompare) { return _date.compareTo( toCompare.getDate()); } } use getDate to get comparison data

9 November 1, 2005Linked Lists9 of 48 Nodes Linked lists contain two kinds of nodes: –have instance variable that points to first node and marks beginning of list –tail node marks end of list as with queues, these don’t hold any list data, just handle “boundary conditions” –nodes in middle are internal nodes only internal nodes hold list data Creating superclass called Node once again allows us to exploit polymorphism; data also familiar… Internal nodes have instance variable _next – _next instance variable is link to next node –nodes know about their neighbor –nodes are smart — they do all the work, distributing intelligence –list can be dumb and only know about first node Internal nodes also have instance variable _data – _data is reference to some Comparable object, e.g., LibraryData –allows node to actually store some information

10 November 1, 2005Linked Lists10 of 48 What can Nodes Do? Each Node class has six capabilities: –searching for an item in the list –inserting a new item in the list –deleting an item in the list –checking for an empty list –returning its data tail node returns null –returning the next node again, tail node returns null Each specialized node can execute its capabilities in specialized way –internal nodes and tail nodes insert items differently How can nodes effect a change over the whole list? Answer: RECURSION!!! Oops, what’s recursion again?

11 November 1, 2005Linked Lists11 of 48 Recursion Review Mike needs advice on being cool and Sara has advice, but he doesn’t know Sara... But Mike knows someone who knows someone who knows Sara… Advice! …

12 November 1, 2005Linked Lists12 of 48 Mike Tries to be Cool So Mike asks his only friend for advice… Mike’s friend asks his only friend for advice, and This friend asks Sara for advice. Do you have advice? Umm... Yup! Umm... Do you have advice? Do you have advice? …

13 November 1, 2005Linked Lists13 of 48 Mike Gets Advice Sara gives advice to friend who asked. Friend gives advice to friend who asked. This friend gives advice to Mike who asked. What’s a sweater? Wear a Sweater! Wear a Sweater … … Wear a Sweater!

14 November 1, 2005Linked Lists14 of 48 List Declaration // new use of the extends keyword: ElementType // generic must implement Comparable interface public class List > { private Node _first; public List() {... } public ElementType search(ElementType itemToFind) {... } public void insert(ElementType newItem) {... } public void delete(ElementType itemToDelete) {... } public boolean isEmpty() {... } } Note that search() not only returns ElementType, but requires it as a parameter Need to make use of Generics here to ensure all of the objects in the list are LibraryData, or whatever the list might require

15 November 1, 2005Linked Lists15 of 48 Don’t be a dummy! Problem: we want to search by Date, but our search method requires a LibraryData. What should we do? Make a dummy LibraryData which just has the date we want to search for –actual data doesn’t matter for the purpose of search it will never be looked at! Create overloaded constructor for LibraryData which just takes a Date as parameter –use this to search the list // in LibraryData class, define a new constructor public LibraryData(Date date) { _date = date; _author = “”; _title = “”; } // declare a list to hold LibraryDatas List list = new List (); // create dummy LibraryData to search with LibraryData itemToFind = new LibraryData(new Date(“Nov 1, 2005”) ); // search for LibraryData with date “Nov 1, 2005” LibraryData result = list.search(itemToFind);

16 November 1, 2005Linked Lists16 of 48 Node Declaration abstract public class Node > { // search returns the internal node whose // _data points to the requested element abstract public Node search (ElementType itemToFind); abstract public Node insert ElementType newItem); abstract public Node delete (ElementType itemToDelete); abstract public boolean isEmpty(); // returns _data abstract public ElementType getData(); abstract public Node getNext(); } Unlike stack and queue, need not hold onto the data after removing it from list –therefore, no ObjectHolder ! Node subclasses are mostly identical –InternalNode, just as with stacks and queues, has two instance variables, _next reference to a Node, and _data reference to an ElementType – TailNode has no extra properties, just defines responses

17 November 1, 2005Linked Lists17 of 48 Subclass Declarations Note: use extends keyword in two different ways. –first use says the ElementType must be a subtype of Comparable –second use is inheritance from Node class InternalNode public class InternalNode > extends Node { private ElementType _data; private Node _next; } TailNode public class TailNode > extends Node { // no instance variables }

18 November 1, 2005Linked Lists18 of 48 Initializing Linked Lists Empty Linked Lists // In class List: public List() { _first = new TailNode (); // list is empty...thus points to TailNode } // In class InternalNode: public InternalNode(ElementType myData, Node myNext) { super(); _data = myData; _next = myNext; } // In class TailNode: public TailNode() { // just uses default constructor super(); } TailNode List Node _first

19 November 1, 2005Linked Lists19 of 48 getData and next methods getData() and getNext() are simple accessor methods for returning node’s data or next node // In class InternalNode public ElementType getData() { return _data; } public Node getNext() { return _next; } TailNode never has any data associated with it, nor does it ever have a next node, so its getData() and getNext() methods return null // In class TailNode public ElementType getData() { return null; } public Node getNext() { return null; }

20 November 1, 2005Linked Lists20 of 48 Searching Need to search for date in sorted list –example: let’s search for today’s date –to simplify the diagrams, we continue the example in terms of Date s only // In class List: // the list delegates to the first node public ElementType search(ElementType itemToFind){ Node result = _first.search(itemToFind); return result.getData(); } InternalNode ElementType _data Node _next TailNode InternalNode ElementType _data Node _next ElementType … Date _date = Oct 30, 2005 ElementType … Date _date = Nov 1, 2005 List Node _first

21 November 1, 2005Linked Lists21 of 48 Node Search — Handoff Nodes only know about their own contents –begin at first node (from List ’s instance variable) TailNode ElementType … Date _date = Oct 30, 2005 ElementType … Date _date = Nov 1, 2005 InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next List Node _first

22 November 1, 2005Linked Lists22 of 48 Internal Node Search Internal node checks its own contents –if keys do not match and search key greater than current node’s data’s date, sends message recursively to its only neighbor TailNode ElementType... Date _date = Oct 30, 2005 ElementType … Date _date = Nov 1, 2005 InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next List Node _first

23 November 1, 2005Linked Lists23 of 48 Eureka! Internal node checks its own contents –if keys match, then this is correct node, and search stops –remember, node is looking for date Nov 1, 2005 TailNode ElementType … Date _date = Nov 1, 2005 InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next List Node _first ElementType … Date _date = Oct 30, 2005

24 November 1, 2005Linked Lists24 of 48 Internal Node Search Code // In class InternalNode public Node search(ElementType itemToFind) { /* if itemToFind has same date as this Node’s _data, return this Node. (See slide 9) */ if (_data.compareTo(itemToFind) == 0) return this; /* if itemToFind is greater than the date of this Node’s _data, recurse */ else if (_data.compareTo(itemToFind) < 0) /* ask neighbor to search and return result */ return _next.search(itemToFind); else /* gone too far; itemToFind is not in list, so return Node with null data to indicate this*/ return new InternalNode(null, null); } How would search be modified if list were not sorted?

25 November 1, 2005Linked Lists25 of 48 Tail Node Search Tail node knows it is the end –tail node ends recursion because there are no data left –if tail node is reached, search failed –therefore tail returns itself (regardless of key) because its getData() method returns null // In class TailNode public Node search(ElementType itemToFind) { return this; // tail node has null _data } TailNode ElementType … Date _date = Oct 30 2005 ElementType … Date _date = Nov 1 2005 InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next List Node _first

26 November 1, 2005Linked Lists26 of 48 Quick Search Summary List ’s _first Node: –points to either Internal Node or Tail Node –starts searching by checking itself Internal Node: –if it holds data with matching key, returns itself –if key being searched for is greater than stored data’s key, passes message recursively to next Node and returns its result to previous Node, and so on… –else, key must not be in list so return a Node with null data Tail Node: –last Node to check and it doesn’t hold a value –so it returns itself (also a Node with null data) to say search failed Therefore, there are two internal ways search can fail; on average only have to search half of list.

27 November 1, 2005Linked Lists27 of 48 Adding a Node ElementType … Date _date = Oct 30 2005 ElementType … Date _date = Nov 1 2005 TailNode ElementType … Date _date = Oct 30 2005 ElementType … Date _date = Nov 1 2005 ElementType … Date _date = Oct 31 2005 TailNode InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next List Node _first List Node _first

28 November 1, 2005Linked Lists28 of 48 Insertion Algorithm New node should be inserted in front of node (7) because it is first node with data value greater than value of new node (5). Why don’t we insert after first node which has data value less than new data value? –there could be many nodes with data value less than new value (1,4) Inserting a node: who’s responsible? –every recursive call of insert returns what caller Node ’s _next should reference, so _next is always assigned result of recursive call –when appropriate node (with data value higher than new data, 7) is found, that node constructs new node pointing to new data (5) and reference to this (7) as new node’s (5) _next node –when that call (on 7) exits, previous call (on 4) finishes by assigning reference returned from call (a reference to new node (5)) to its _next, thus inserting that new node (after 4) 5 147 new

29 November 1, 2005Linked Lists29 of 48 Original List TailNode ElementType … Date _date = Oct 30 2005 ElementType … Date _date = Nov 1 2005 InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next List Node _first

30 November 1, 2005Linked Lists30 of 48 List Add Code List simply tells first node to insert –updates _first to reference whatever is returned by recursive call // In class List: public void insert(ElementType newItem) { _first = _first.insert(newItem); } TailNode ElementType … Date _date = Oct 30 2005 ElementType … Date _date = Nov 1 2005 ElementType … Date _date = Oct 31 2005 newItem InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next List Node _first

31 November 1, 2005Linked Lists31 of 48 Add Node (cont.) Our new Date Oct 31 2005 is greater than Oct 30 2005 so internal node passes message along TailNode ElementType … Date _date = Oct 30 2005 ElementType … Date _date = Nov 1 2005 ElementType … Date _date = Oct 31 2005 newItem InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next List Node _first Internal node passes message along and returns itself if new key is greater than its stored data, else it inserts the data before itself, and returns reference to newly created node

32 November 1, 2005Linked Lists32 of 48 Add Node (cont.) Our new Date Oct 31 2005 is less than Nov 1 2005 so internal node knows it must take care of inserting new data. TailNode ElementType … Date _date = Oct 30 2005 ElementType … Date _date = Nov 1 2005 ElementType … Date _date = Oct 31 2005 newItem InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next List Node _first

33 November 1, 2005Linked Lists33 of 48 Internal Node Code // In class InternalNode public Node insert(ElementType newItem) { /* if data is less than newItem, then recurse to insert newItem further into list */ if (_data.CompareTo(newItem) < 0) { _next = _next.insert(newItem); return this; } /* else create a new InternalNode to store the data and give it this node as its _next. */ else { Node result = new InternalNode (newItem, this); return result; } } How would we change this code if we did not want to allow duplicate keys to be inserted in List ?

34 November 1, 2005Linked Lists34 of 48 Adding New Node New Date Oct 31 2005 needs new internal node –node storing Nov 1 2005 creates a new node, passing data and a reference to itself to the constructor –new node’s constructor sets _next to reference passed in (Nov 1 2005’s) node –new node’s constructor also sets its _data to data passed in, newItem. –previous node sets _next to new node TailNode ElementType … Date _date = Oct 30 2005 ElementType … Date _date = Nov 1 2005 ElementType … Date _date = Oct 31 2005 newItem InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next List Node _first

35 November 1, 2005Linked Lists35 of 48 Back in current (Nov 1 2005’s) node’s insert: –returned reference to new node (Oct 31 2005) –previous invocation of insert (for Oct 30 2005) set its _next reference to the new node (Oct 31 2005) –now list is properly linked, with new node inserted Thus the predecessor got a link to the new node TailNode ElementType … Date _date = Oct 30 2005 ElementType … Date _date = Nov 1 2005 ElementType … Date _date = Oct 31 2005 InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next List Node _first

36 November 1, 2005Linked Lists36 of 48 Inserting at the Tail What if we wanted to insert Nov 18 2005 instead? Nov 18 2005 belongs after Nov 1 2005 –message gets sent through internal nodes to tail node TailNode ElementType … Date _date = Oct 30 2005 ElementType … Date _date = Nov 1 2005 ElementType … Date _date = Nov 18 2005 newItem InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next List Node _first

37 November 1, 2005Linked Lists37 of 48 Tail Node Insert Code // In class TailNode public Node insert(ElementType newItem) { /* we have no alternatives, so insert the node right here */ return new InternalNode (newItem, this); } Similar to InternalNode ’s insert, except we don’t have to check if data belongs later in list –can’t insert node after tail –if recursion gets to tail node, tail node always inserts directly before it, no questions asked –tail must insert a new node and give tail as new node’s _next

38 November 1, 2005Linked Lists38 of 48 After Inserting at Tail TailNode InternalNode ElementType _data Node _next ElementType … Date _date = Oct 30 2005 ElementType … Date _date = Nov 18 2005 ElementType … Date _date = Nov 1 2005 InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next List Node _first

39 November 1, 2005Linked Lists39 of 48 Deleting a Node Deleting Nov 1 2005 TailNode ElementType … Date _date = Oct 30 2005 ElementType … Date _date = Nov 18 2005 ElementType … Date _date = Nov 1 2005 InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next List Node _first to this list:from this list:

40 November 1, 2005Linked Lists40 of 48 Deleting in English We find the Node whose _data matches our itemToFind ’s key Need that Node ’s reference to its _next Node –we want to re-link the Node previous to the found Node to the Node after, thereby deleting the found Node Therefore sender forgets about the found Node which has graciously provided the reference to the Node following it

41 November 1, 2005Linked Lists41 of 48 Delete (cont.) Let’s delete Nov 1 2005. So we send message to List, which sends it to _first, which sends it... // In class List; public void delete(ElementType itemToDelete) { _first = _first.delete(itemToDelete); } TailNode ElementType … Date _date = Oct 30 2005 ElementType … Date _date = Nov 18 2005 ElementType … Date _date = Nov 1 2005 List Node _first InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next

42 November 1, 2005Linked Lists42 of 48 List Delete Code If _first ’s data matches itemToDelete it returns _next (thereby deleting itself); otherwise it returns itself. –reassigning _next either keeps same node or references its next node, effectively bypassing internal node to be deleted TailNode ElementType … Date _date = Oct 30 2005 ElementType … Date _date = Nov 18 2005 ElementType … Date _date = Nov 1 2005 List Node _first InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next

43 November 1, 2005Linked Lists43 of 48 Internal Node Delete Code // In class InternalNode public Node delete(ElementType itemToDelete) { // temporary variable to store node to return Node nodeToReturn = this; if (_data.compareTo(itemToDelete) == 0) nodeToReturn = _next; else if (_data.compareTo(itemToDelete) < 0) _next = _next.delete(itemToDelete); return nodeToReturn; } If keys are equal –return _next to become predecessor’s new next node If _data ’s key is less than itemToDelete ’s key –set _next to whatever is returned by call to successor (either successor itself or its neighbor) –return this which will be assigned to predecessor’s _next (thus not changing the relative order) Otherwise –node can’t be in list and can’t be deleted –return this as predecessor’s _next

44 November 1, 2005Linked Lists44 of 48 Delete (cont.) Oct 30 2005 node is not node to be deleted so it passes message on to _next, Nov 1 2005’s node else if (_data.compareTo(itemToDelete) < 0) { _next = _next.delete(itemToDelete); } TailNode ElementType … Date _date = Oct 30 2005 ElementType … Date _date = Nov 18 2005 ElementType … Date _date = Nov 1 2005 List Node _first InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next InternalNode ElementType _data Node _next

45 November 1, 2005Linked Lists45 of 48 Delete (cont.) This node is the one to be deleted so it returns a reference to its next, Nov 18 2005’s node if (_data.compareTo(itemToDelete) == 0) nodeToReturn = _next; InternalNode ElementType _data Node _next TailNode InternalNode ElementType _data Node _next ElementType … Date _date = Oct 30 2005 ElementType … Date _date = Nov 18 2005 ElementType … Date _date = Nov 1 2005 ElementType _data Node _next InternalNode nodeToReturn List Node _first Node to be deleted ElementType _data Node _next InternalNode ElementType _data Node _next Recursion returns to previous node, for key Oct 30 2005 –nodeToReturn now references node containing key Nov 18 2005, successor to Nov 1 2005. Oct 30 2005 re-links list by resetting its _next _next = _next.delete(itemToDelete); return nodeToReturn; //initially set to this

46 November 1, 2005Linked Lists46 of 48 Tail Node Delete Code // In class TailNode public Node delete(ElementType itemToDelete) { return this; } If delete message ever gets to tail node, there’s nothing to delete –no links should change, so tail node returns this every time

47 November 1, 2005Linked Lists47 of 48 Implementing isEmpty() List acts as usual and relays message to first node Internal node will return false, tail node will return true –true means List asked tail, so there are no internal nodes in List (it is empty) –false means first is internal node, so there is at least one node in list (it is not empty) Sound familiar? It is the same as queues!

48 November 1, 2005Linked Lists48 of 48


Download ppt "LINKED LISTS Linear Linked List. November 1, 2005Linked Lists2 of 48 Linked Lists Like stacks and queues, linked lists are lists of nodes that point to."

Similar presentations


Ads by Google