Download presentation
Presentation is loading. Please wait.
Published byBethanie Griffith Modified over 8 years ago
1
Linked Lists Chapter 4
2
Linked Structures: Motivations Arrays have fixed size –Problematic for data structures of arbitrary size Arrays order items physically –Must perform expensive shift when inserting or deleting Linked structures (such as lists) can –Grow dynamically –Handle insertions and deletions without shifting Draw a few examples …
3
Faking it with “Resizable” Arrays Can allocate a new array and copy into it to make the array appear to be resizable Good growth policy: new array is double the previous size. –In 311 you’ll see that the amortized cost is much lower than fixed increment growth. java.util.Vector does this But the copying is expensive: in many applications, linked lists grow with lower cost
4
Object References Variables that reference objects Diagram memory and compare: int p = 0; Integer p = new Integer(0); // only if you’ll use it Example: Integer p; // defaults to null Integer q; p = new Integer(5); p = new Integet(6); q = p; q = new Integer(9); p = null; q = p;
5
Garbage Collection What happens to objects that have no references to them? They are inaccessible to the program Java system will remove them and recycle the memory (usually when low on memory) How this is done is up to the implementation I’ll describe two approaches: –Reference counting (has problems with cycles) –Mark and sweep, or tracing Compaction is also important
6
More on Object References Equality operators == and != compare values of references, not the objects MyNumber x = new MyNumber(9); MyNumber y = new MyNumber(9); MyNumber z = x; x == y; // ? x == z; // ? Parameter passing is reference based: value of actual reference is copied to formal parameter new may throw exception if unable to instantiate object
7
Reference-Based Linked Lists Out of what do we make linked lists? A node consists of a data item and a reference to a node As usual, declare these data fields private and provide assessor and mutator methods To be generically useful, data items can be Object references.
8
Your Basic Generic Node public class Node { private Object item; private Node next; public Node(Object newItem) { item = newItem; next = null; } // end constructor public Node(Object newItem, Node nextNode) { item = newItem; next = nextNode; } // end constructor public void setItem(Object newItem) { item = newItem; } // end setItem public Object getItem() { return item; } // end getItem public void setNext(Node nextNode) { next = nextNode; } // end setNext public Node getNext() { return next; } // end getNext } // end class Node
9
Node Example Work this out on paper: Node n = new Node(new Integer(1)); Node p = new Node(new Integer(3), n); Let’s keep going: n.setNext(new Node(new Integer(5)); (n.getnext()).setItem(4) (p.getnext()).setItem(new Node(new Integer(2)); Why not? Nodes are Objects too!
10
Referencing and Traversing a List Usually we keep track of the front of the list with a reference variable: Node head; // code to build the list goes here Suppose head references a list of objects. We can process each item as follows: for (Node curr = head; curr != null; curr = curr.getNext()) { // do something to curr.getItem(), e.g.: System.out.println(curr.getItem()); }
11
Deleting from a Linked List (first try) Suppose we want to delete a node from a list It is referenced by a variable curr Let’s do it … Oops! We can’t get to the node before it! We could have stopped curr one node earlier and done: curr.setNext((curr.getNext).getNext); But we usually use two references to avoid chains of getNext.getNext …
12
Deleting from a Linked List To delete a node from a list, we must modify the previous node to reference the next node So we use prev = the node before the one to delete curr = the node we want to delete prev.setNext(curr.getNext()); What about the first node? head = head.getNext(); Let’s not forget garbage collection: curr.setItem(null); // if we don’t plan to use curr.setNext(null); // it elsewhere curr = null;
13
Inserting Into a Linked List Suppose we want to put a node between two nodes. We must –modify the previous node to reference the new node –keep track of the next node so the new node can point to it prev = the node after which we want to insert curr = the node before which we want to insert newNode = the node we want to insert newNode.setNext(curr); prev.setNext(newNode); Anything else?
14
More Inserting What about inserting at the front? newNode.setNext(head); head = newNode; Or inserting at the end? –The previous code actually works if curr is null, which it will be if curr == prev.getNext(); newNode.setNext(curr); prev.setNext(newNode); OK, how do we find prev and curr ?
15
Finding your place in a list Gist: after checking for special case at head of list, move prev and curr together with prev = curr; curr = curr.getNext(); until you get to where you want to be, or you reach the end of the list “Where you want to be” is dependent on the application Common example: sorted list. Here’s how …
16
Finding Place in Sorted List of int Two ways of finding newValue ’s place prev = null; curr = head; while ((curr != null) && (newValue > curr.getItem())) { prev = curr; curr = curr.getNext(); } // ALTERNATIVELY: for (prev = null, curr = head; (curr != null) && (newValue > curr.getItem()); prev = curr, curr = curr.getNext()) {} At this point what does prev == null imply? curr == null ? Why must curr != null go first?
17
Will > work on a list of Objects? Nah. If the class implements java.lang.Comparable: public class MyClass implements java.lang.Comparable {... public int compareTo(Object rhs) { // returns 0 if “equal” // returns 1 if rhs is “greater” // returns -1 if rhs is “less” } } Then we can write: for (prev = null, curr = head; (curr != null) && (newValue.compareTo(curr.getItem()) > 0); prev = curr, curr = curr.getNext()) {}
18
Reference-based Implemenation of ADT List public class ListReferenceBased implements ListInterface { // reference to linked list of items private Node head; private int numItems; // number of items in list public ListReferenceBased() { numItems = 0; head = null; } // end default constructor public boolean isEmpty() { return numItems == 0; } // end isEmpty public int size() { return numItems; } // end size
19
ADT List continued: Node private Node find(int index) { // -------------------------------------------------- // Locates a specified node in a linked list. // Precondition: index is the number of the desired // node. Assumes that 1 <= index <= numItems+1 // Postcondition: Returns a reference to the desired // node. // -------------------------------------------------- Node curr = head; for (int skip = 1; skip < index; skip++) { curr = curr.getNext(); } // end for return curr; } // end find
20
ADT List continued: Object public Object get(int index) throws ListIndexOutOfBoundsException { if (index >= 1 && index <= numItems) { // get reference to node, then data in node Node curr = find(index); Object dataItem = curr.getItem(); return dataItem; } else { throw new ListIndexOutOfBoundsException( "List index out of bounds exception on get"); } // end if } // end get
21
ADT List continued: Add public void add(int index, Object item) throws ListIndexOutOfBoundsException { if (index >= 1 && index <= numItems+1) { if (index == 1) { // insert the new node containing item at // beginning of list Node newNode = new Node(item, head); head = newNode; } else { Node prev = find(index-1); // insert the new node containing item after // the node that prev references Node newNode = new Node(item, prev.getNext()); prev.setNext(newNode); } // end if numItems++; } else { throw new ListIndexOutOfBoundsException( "List index out of bounds exception on add"); } // end if } // end add
22
ADT List continued: Remove public void remove(int index) throws ListIndexOutOfBoundsException { if (index >= 1 && index <= numItems) { if (index == 1) { // delete the first node from the list head = head.getNext(); } else { Node prev = find(index-1); // delete the node after the node that prev // references, save reference to node Node curr = prev.getNext(); prev.setNext(curr.getNext()); } // end if numItems--; } // end if else { throw new ListIndexOutOfBoundsException( "List index out of bounds exception on remove"); } // end if } // end remove
23
ADT List continued: RemoveAll public void removeAll() { // setting head to null causes list to be // unreachable and thus marked for garbage // collection head = null; numItems = 0; } // end removeAll } // end ListReferenceBased
24
To be added Recursive processing Comparing array-based and reference-based implementations Tail references Dummy head nodes Circular lists Doubly linked lists More examples covered in class
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.