Lecture 6: Linked Data Structures

Slides:



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

DATA STRUCTURES USING C++ Chapter 5
List Implementations That Link Data Chapter 6. 2 Chapter Contents Linked Data Forming a Chains The Class Node A Linked Implementation Adding to End of.
Chapter 3: Arrays, Linked Lists, and Recursion
1 Linked-list, stack and queue. 2 Outline Abstract Data Type (ADT)‏ Linked list Stack Queue.
(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.
Linked Bag Chapter 3.
Linked Lists Chapter 4. Linked Structures: Motivations Arrays have fixed size –Problematic for data structures of arbitrary size Arrays order items physically.
2005MEE Software Engineering Lecture 7 –Stacks, Queues.
Sorted Lists Chapter Chapter Contents Specifications for the ADT Sorted List Using the ADT Sorted List A Linked Implementation The Method add The.
CSE 501N Fall ‘09 10: Introduction to Collections and Linked Lists 29 September 2009 Nick Leidenfrost.
Lists List Implementations. 2 Linked List Review Recall from CMSC 201 –“A linked list is a linear collection of self- referential structures, called nodes,
 2015, Marcus Biel, Linked List Data Structure Marcus Biel, Software Craftsman
1 CS162: Introduction to Computer Science II Abstract Data Types.
Lists and the Collection Interface Chapter 4. Chapter 4: Lists and the Collection Interface2 Chapter Objectives To become familiar with the List interface.
Chapter 3 Lists, Stacks, Queues. Abstract Data Types A set of items – Just items, not data types, nothing related to programming code A set of operations.
Linked Data Structures
These notes are intended for use by students in CS0445 at the University of Pittsburgh and no one else These notes are provided free of charge and may.
Lecture 6 of Computer Science II
Review Array Array Elements Accessing array elements
The List ADT.
Pointers and Linked Lists
Pointers and Linked Lists
Introduction to Linked Lists
Lectures linked lists Chapter 6 of textbook
Linked Lists Chapter 5 (continued)
Arrays in PHP are quite versatile
UNIT-3 LINKED LIST.
An Introduction to Sorting
Queues Queues Queues.
LINKED LISTS CSCD Linked Lists.
Top Ten Words that Almost Rhyme with “Peas”
Prof. Neary Adapted from slides by Dr. Katherine Gibson
Introduction to Linked Lists
structures and their relationships." - Linus Torvalds
These notes are intended for use by students in CS0445 at the University of Pittsburgh and no one else These notes are provided free of charge and may.
Queue, Deque, and Priority Queue Implementations
A Bag Implementation that Links Data
Queue, Deque, and Priority Queue Implementations
Linked Lists.
Topic 11 Linked Lists -Joel Spolsky
These notes are intended for use by students in CS0445 at the University of Pittsburgh and no one else These notes are provided free of charge and may.
List Data Structure.
Stacks, Queues, and Deques
Further Data Structures
Linked Lists.
Programming II (CS300) Chapter 07: Linked Lists and Iterators
CS2013 Lecture 4 John Hurley Cal State LA.
Dynamic Data Structures and Generics
Hash Tables Chapter 12 discusses several ways of storing information in an array, and later searching for the information. Hash tables are a common.
A List Implementation That Links Data
Cs212: Data Structures Computer Science Department Lecture 7: Queues.
CS210- Lecture 5 Jun 9, 2005 Agenda Queues
Chapter 4 Unordered List.
Dynamic Data Structures and Generics
Introduction to Data Structure
Hash Tables Chapter 12 discusses several ways of storing information in an array, and later searching for the information. Hash tables are a common.
Data Structures Unsorted Arrays
CSC 143 Java Linked Lists.
Data Structures & Algorithms
Programming II (CS300) Chapter 07: Linked Lists
Stacks, Queues, and Deques
TCSS 143, Autumn 2004 Lecture Notes
Linked Lists Chapter 5 (continued)
CSE 373 Set implementation; intro to hashing
structures and their relationships." - Linus Torvalds
Linked Lists Chapter 5 (continued)
A List Implementation That Links Data
Topic 11 Linked Lists -Joel Spolsky
Presentation transcript:

Lecture 6: Linked Data Structures Let's concentrate on the drawbacks of contiguous memory Is there an alternative way of storing a collection of data that avoids these problems? What if we can allocate our memory in small, separate pieces, one for each item in the collection Now we allocate exactly as many pieces as we need Now we do not have to shift items, since all of the items are separate anyway Draw on board

Lecture 6: Linked Data Structures But how do we keep track of all of the pieces? We let the pieces keep track of each other! Let each piece have 2 parts to it One part for the data it is storing One part to store the location of the next piece This is the idea behind a linked-list firstNode data data data data

Lecture 6: Linked Data Structures Idea of Linked List: If we know where the beginning of the list is And each link knows where the next one is Then we can access all of the items in the list Our problems with contiguous memory now go away Allocation can be done one link at a time, for as many links as we need New links can be "linked up" anywhere in the list, without shifting needed Demonstrate on board

How can we implement linked lists? Lecture 6: Linked Lists How can we implement linked lists? The key is how each link is implemented As we said, two parts are needed, one for data and one to store the location of the next link We can do this with a self-referential data type class Node { private T data; private Node next; … A NODE is a common name for a link in a linked-list Note why it is called "self-referential"

Lecture 6: Singly Linked Lists Linked-List Implementation Variations Singly Linked List The simple linked-list we just discussed is a singly-linked list Links go in one direction only We can easily traverse the list from the front to the rear We CANNOT go backwards through the list at all This list is simple and (relatively) easy to implement, but has the limitations of any "one way street" This implementation is developed in Chapter 3 firstNode

Lecture 6: Singly Linked Lists There are other variations of linked lists: Doubly linked list Circular linked list We will discuss these later For now we will keep things very simple

Lecture 6: Linked Bag Implementation Let's look at this implementation a bit public class LinkedBag<T> implements BagInterface<T> { private Node firstNode; private int numberOfEntries; … private class Node private T data; private Node next; private Node(T dataPortion) { this(dataPortion, null); } private Node(T dataPortion, Node nextNode) { data = dataPortion; next = nextNode; } } // class Node } // class LinkedBag Note that Node is a private inner class

Lecture 6: Node As an Inner Class Why is it done this way? Since Node is declared within LinkedBag, methods in LinkedBag can access private declarations within Node This is a way to get "around" the protection of the private data LinkedBag will be needing to access data and next of its Nodes in many of its methods We could write accessors and mutators within Node to allow this access However, it is simpler for the programmer if we can access data and next directly They are still private and cannot be accessed outside of LinkedBag On the downside, with this implementation, we cannot use Node outside of the LinkedBag class

Lecture 6: Linked Bag Implementation Now let's see how we would implement some of our BagInterface methods public boolean add (T newEntry) { Node newNode = new Node(newEntry); // create Node newNode.next = firstNode; // link it to prev. front firstNode = newNode; // set front to new Node numberofEntries++; // increment entries return true; } // method add For the linked bag we add new values at the front, while we added new values at the end of the array. Since the Bag is not sorted, it does not logically matter. Compare to add() in the array implementation What is different? Is this a problem?

Lecture 6: Linked Bag Implementation Trace on board Try a few adds in example Note insertion is at the front of the bag New node is created and newEntry is put in it New node becomes new front of list, push old front back Since BagInterface does not specify where to insert, we again do what is most convenient for our implementation Are there any special cases Ex: What if the bag is empty? firstNode will be null Will this be a problem? Any other special cases here?

Lecture 7: Linked Bag Implementation Ok, that operation was simple How about something that requires a loop of some sort? Let’s look at the contains() method Just like for the array, we will use sequential search Just like for the array, we start at the beginning and proceed down the bag until we find the item or reach the end So what is different? How do we “move down” the bag? How do we know when we have reached the end? Discuss Let’s look at the code

Lecture 7: Linked Bag Implementation public boolean contains(T anEntry) { boolean found = false; Node currentNode = firstNode; while (!found && (currentNode != null)) if (anEntry.equals(currentNode.data)) found = true; else currentNode = currentNode.next; } // end while return found; } // end getReferenceTo Loop will terminate when either found == true or null is reached (in which case found == false)

Lecture 7: Linked Bag Implementation Let’s look at one more operation: public boolean remove(T anEntry) We want to remove an arbitrary item from the Bag How do we do this? Think about the contains() method that we just discussed How is remove similar and how is it different? Find the entry in question But now we need more than just a boolean result We must store a reference to the actual node so that we can do something with it Then remove it Must unlink the node from the list Let’s think about this

Lecture 7: Linked Bag Implementation Consider again the properties of a Bag The data is in no particular order We could remove the actual Node in question but perhaps we can do it more easily The front Node is very easy to remove Trace on board So let’s copy the item in the front Node to the Node that we want to remove Then we remove the front Node Logically, we have removed the data we want to remove Keep in mind that the Nodes are not the data – they are simply a mechanism for accessing the data Also keep in mind that this would NOT be ok if the data needs to stay in some kind of order Note: The idea here is similar to what we did with the array implementation. However, there is an important difference. With the array, by moving an item into the empty spot rather than shifting, we are saving considerably on the runtime (going from linear runtime to constant runtime). For the linked implementation, the actual removal process is still only a few steps even in place, as we will see later with some other implementations. However, in either case, we are still required to find the object first, which takes linear time in an unordered collection such as a Bag.

Lecture 7: Linked Bag Implementation private Node getReferenceTo(T anEntry) { boolean found = false; Node currentNode = firstNode; while (!found && (currentNode != null)) if (anEntry.equals(currentNode.data)) found = true; else currentNode = currentNode.next; } // end while return currentNode; } // end getReferenceTo Note that the logic here is the same as for contains What is different is what is returned

Lecture 7: Linked Bag Implementation public boolean remove(T anEntry) { boolean result = false; Node nodeN = getReferenceTo(anEntry); if (nodeN != null) nodeN.data = firstNode.data; // copy data from firstNode = firstNode.next; // first Node and numberOfEntries--; // delete that Node result = true; // Operation succeeds } // end if return result; } // end remove Note that this returns boolean rather than the entry that is being removed

Lecture 7: Linked Bag Implementation There are other methods that we have not discussed Look over them in the text and in the source code Look again at Example6.java Note (as we discussed) how the data is ordered differently in the different Bag implementations However, it is irrelevant to the functionality

Lecture 7: Node as a Separate Class Node class as a separate (non-inner) class Some OO purists believe it is better to never "violate" the private nature of a class' data Making Node separate also allows it to be reused If done this way, the Node class must also be a parameterized type class Node<T> { private T data; // data portion private Node<T> next; // link to next node … And now in class LinkedList we would have private Node<T> firstNode;

Lecture 7: Node as a Separate Class Access to next and data fields must now be done via accessors and mutators, so these must be included in the Node<T> class Ex: getData(), getNextNode() accessors Ex: setData(), setNextNode() mutators Look at rest of Node<T> class code See handout Let's look at a method in LinkedBag.java we have already discussed, but now using this variation remove() method Differences from previous version are shown in red

Lecture 7: Node as a Separate Class public boolean remove(T anEntry) { boolean result = false; Node<T> nodeN = getReferenceTo(anEntry); if (nodeN != null) nodeN.setData(firstNode.getData()); firstNode = firstNode.getNextNode(); numberOfEntries-- result = true; } return result; Note that getReferenceTo() would also be different, using accessors and mutators rather than direct access to the nodes

Consider another ADT: the List Lecture 7: ADT List Consider another ADT: the List We can define this in various ways – by its name alone it is perhaps only vaguely specified Let's look at how the text looks at it: Data: A collection of objects in a specific order and having the same data type The number of objects in the collection Operations: add(newEntry) add(newPosition, newEntry) remove(givenPosition)

See Ch. 12 for detailed specifications Lecture 7: ADT List clear() replace(givenPosition, newEntry) getEntry(givenPosition) toArray() contains(anEntry) getLength() isEmpty() See Ch. 12 for detailed specifications Note that indexing for this ADT starts at 1, not 0 Odd but this is how the author defined it We will look at a few of these and see the similarities to and differences from our Bag ADT

Lecture 7: Using a List Recall that at this point we are looking at a List from a user's point of view So what can we use it for? A List is a very general and useful structure See ListInterface.java For example: We can use it for Last In First Out behavior (how?) We can use it for First in First Out behavior (how?) We can access the data by index and add/remove at a given location We can search for an item within the list

How about using it as a Bag? Lecture 7: ADT List How about using it as a Bag? We could but would need to add the Bag methods It may not be the ideal ADT for some of these behaviors We will look at how some of these operations are done and their efficiencies soon However, we may choose to use it because it can do ALL of these things See Example7.java

Lecture 7: Java Standard List Standard Java has a List interface Superset of the operations in author's ListInterface Some operations have different names Special cases may be handled differently Indexing starts at 0 But the idea is the same Look up List in the Java API See Example7b.java

Lecture 8: Implementing a List Ok, now we need to look at a list from the implementer's point of view How to represent the data? Must somehow represent a collection of items (Objects) How to implement the operations? As discussed previously, the implementation of the operations will be closely related to the representation of the data Minimally the data representation will "suggest" ways of implementing the operations

Lecture 8: Linked List Implementation Let’s first implement our ListInterface using a linked data structure [Note: The text uses array first but we are doing linked version first to aid with next assignment] Much of the implementation is identical to our LinkedBag Singly-linked list structure Node inner class with data and next fields Adding a new item at the front of the list is identical Finding an item in the list is identical However, there are some important differences between the two

Lecture 8: Linked List Implementation The List interface requires data to be kept in positional order Thus, we cannot arbitrarily move data around Bag always removed Nodes from the front and moved data to allow arbitrary delete We can also insert and remove in a given position Will need to add and remove Nodes from the middle of the list This was not needed for LinkedBag Let’s focus on the parts of the LL that differ from the LinkedBag For example, consider the remove(int givenposition) method

Lecture 8: Linked List Implementation public T remove(int givenPosition) What do we need to do here? We must first get to the object at givenPosition (i) There is a private method getNodeAt() to do this We will see the code soon Then we must "remove" it We must do this in such a way that the rest of the list is still connected We must link the previous node to the next node firstNode Previous Node Next Node i

Lecture 8: Linked List Implementation But notice that by the time we find the node we want to delete, we have "passed" up the node we need to link Since the links are one way we can't go back Solution? Find the node BEFORE the one we want to remove Then get the one we want to remove and the one after that, and change the links appropriately firstNode nodeBefore nodeToRemove nodeAfter i

Lecture 8: Linked List Implementation Let's look at the getNodeAt() method: Note that we start at the front of the list and follow the links down to the desired index Q: How does this compare to getting to a specific index in an array? /** Task: Returns a reference to the node at a given position. * Precondition: List is not empty; 1 <= givenPosition <= length. */ private Node getNodeAt(int givenPosition) { assert !isEmpty() && (1 <= givenPosition) && (givenPosition <= numberOfEntries); Node currentNode = firstNode; // traverse the list to locate the desired node for (int counter = 1; counter < givenPosition; counter++) currentNode = currentNode.getNextNode(); assert currentNode != null; return currentNode; } // end getNodeAt A: We can directly access any location in the array, but must traverse through the list to get to a location in the Linked List. This difference in access time for a specific location in a list is a significant difference in the array and linked implementations.

Lecture 8: Linked List Implementation What if givenPosition > numberOfEntries? So why don't we handle this possible error? The method is private The idea is that as class designers, we make sure the error cannot occur – that is why it is an "assert" Users of the class cannot call this method, so there is no problem for them Ex: See public T getEntry(int givenPosition) The index test is done BEFORE getNodeAt() is called An assertion error This will crash our program!

Lecture 8: Linked List Implementation Other issues? What else should we be concerned with when trying to delete a node? Are there any special cases we have to worry about? This is VERY IMPORTANT in many data structures and algorithms We discussed this for BagInterface but there were not really any problems But what about for ListInterface? if the index is invalid we cannot delete deleting the front node deleting the last remaining node (also the front node) Let's see, if the front node is deleted, the node before it will be ??????????? Special case!!!

Lecture 8: Linked List Implementation Let's look at the code: public T remove(int givenPosition) { T result = null; // initialize return value if ((givenPosition >= 1) && (givenPosition <= numberOfEntries)) assert !isEmpty(); if (givenPosition == 1) // case 1: remove first entry result = firstNode.getData(); firstNode = firstNode.getNextNode(); } else // case 2: givenPosition > 1 Node nodeBefore = getNodeAt(givenPosition-1); Node nodeToRemove = nodeBefore.getNextNode(); result = nodeToRemove.getData(); Node nodeAfter = nodeToRemove.getNextNode(); nodeBefore.setNextNode(nodeAfter); } // end if numberOfEntries--; return result; // return result } // end if else throw new IndexOutOfBoundsException("Illegal Index"); } // end remove Special Case: First Node Normal Case Special Case: Invalid Index

Lecture 8: Singly Linked List Variations First and Last References We discussed before that if we are inserting a node at the end of the list, we must traverse the entire list first to find the last previous node This is inefficient if we do a lot of adds to the end of the list [we'll discuss the particulars later] We could save time if we kept an additional instance variable (lastNode) that always refers to the end of the list Now adding to the end of the list is easy! However, it has some other interesting issues

Lecture 8: Singly Linked List Variations See on board and discuss what the issues might be Thus, adding an extra instance variable to save time with one operation can increase the complexity of other operations Only by a small amount here, but we still need to consider it Let's look at an operation both without and with the lastNode reference Text looks at add() methods so let's look at a different one Let's try remove() Let's think about this

Lecture 8: Singly Linked List Variations When, if at all, will we need to worry about the lastNode reference? With all of these methods we want to think about The "normal" case, or what we usually expect The "special" case that may only occur under certain circumstances Normal case: We remove a node from the "middle" of the list and the lastNode reference does not change at all Can we think of 2 special cases here? They are somewhat related

Lecture 8: Singly Linked List Variations Removing the last node in the list This clearly will affect the lastNode reference How do we know when this case occurs? How do we handle it Removing the only node in the list Clearly this case is also 1) above, since the only node is also the last node However, we should consider it separately, since there may be special things that must be done if the list is becoming empty How do we handle it?

Lecture 8: Singly Linked List Variations public T remove(int givenPosition) { T result = null; if ((givenPosition >= 1) && (givenPosition <= numberOfEntries)) assert !isEmpty(); if (givenPosition == 1) result = firstNode.getData(); firstNode = firstNode.getNextNode(); if (numberOfEntries == 1) lastNode = null; } else Node nodeBefore = getNodeAt(givenPosition-1); Node nodeToRemove = nodeBefore.getNextNode(); Node nodeAfter = nodeToRemove.getNextNode(); nodeBefore.setNextNode(nodeAfter); result = nodeToRemove.getData(); if (givenPosition == numberOfEntries) lastNode = nodeBefore; } // end if numberOfEntries--; } // end if else throw new IndexOutOfBoundsException("Illegal Index"); return result; } // end remove Code to handle deleting only node Code to handle deleting last node

Lecture 8: Singly Linked List Variations Circular Linked List Now instead of null, the last node has a reference to the front node What is good about this? Which node(s) should we keep track of? Why? Think about adding at the beginning or end Can be effectively used for a Queue (see board) We will look at this more later lastNode

Lecture 8: Other Linked List Variations Doubly Linked List Each node has a link to the one before and the one after Call them previous and next Now we can easily traverse the list in either direction Gives more general access and can be more useful This is more beneficial if we have a reference to the end of the list as well as the beginning, or we make it circular Used in standard JDK LinkedList and in author’s Deque Some operations may be somewhat faster But more overhead involved What overhead do we mean here? We may look in more detail if we have time