260 likes | 381 Views
COP 3540 Data Structures with OOP. Chapter 5 Linked Lists. Different Storage Structure. Arrays: Some real advantages and disadvantages depending on whether or not the array was sorted AND what you wanted to do Insert Delete Search…
E N D
COP 3540 Data Structures with OOP Chapter 5 Linked Lists
Different Storage Structure • Arrays: • Some real advantages and disadvantages depending on whether or not the array was sorted AND what you wanted to do • Insert • Delete • Search… • Second most commonly used data storage structure after arrays: the Linked List. • Extremely versatile. • Will discuss strengths and weaknesses
Links • “In a linked list, each dataitem is embedded in a link. • (I sometimes call these nodes or cells). • (You may not use the link in the API for link operations in your program assignments.) • Each link object contains • data – (any kind; any amount) and a • reference (points to the next item in the list).
Links. • Consider: class Link { public int iData //some data public double dData //more data public Link next; // reference to next link } // end class definition • This kind of class definition is called self-referential, because it contains a link that points to the next node that is of the same type as itself. • We can have many data items in a link. But the key is the nextreference to the ‘next’ link.
Basic Types • Note: ‘next’ is only a reference to the next link. • Next has the address of the next object or null. • For ‘next’ to have meaning, there must be an object created and its address placed into ‘next.’
References • In an array, we merely add one (1) to access the next physical item. • In a linked-list, we follow a chain of links – from one link to another to find a desired link. • It is unlikely you have the direct access of a specific link to directly access • (although processing linked lists does allow you to save off addresses, if you wish…)
A Simple Linked List • We will • insert items and delete items at the beginning of the list and • display items in a linked list. • Here’s the Link Class class Link { public int iData; public double dData; Let’s make these ‘public’ for now… public Link next; // ------------------------------------------------------------------------ public Link (int id, double dd) // Constructor { iData = id; dData = dd; } // end Constructor // ----------------------------------------------------------------------- public void displayLink() { System.out.print(“{ + iData + “,” + dData + “} ”); } // end displayLink() } // end class Link Clearly the Constructor builds the data in the link (but not the next field) and the display() prints it out. Why does the Constructor not build the ‘next’ field??
The LinkList Class • Special class. Note: your authors call this class, LinkList. • Only contains the address of the first element in the linked list. Class LinkList { private Link first; // reference to an object (special object) of type Link. Name is ‘first.’ // ------------------------------------------- public void LinkList() // Constructor { first = null; // Can see the value of ‘first’ is null – until we start building links. // It doesn’t point to anything yet. } // end constructor public boolean isEmpty() { return (first==null); } // end isEmpty() // other methods. } // end LinkList
The insertFirstMethod • We are now going to build and insert nodes into an existing linked list. • See next slide: • First points to next link (value of 42) which points to nextlink (value of 7), etc. Lastlink points to null. • Now insertfirst() a new Link w/value of 33 at first part of the Linked List which then points to the previous first link, who has value of 42… • Consider the drawing and then insertfirst():
Linked List – already built Linked List Identify the parts: links, next, values, first, … First rear Next (link) Data 42 7 98 14 null 33 First Insert a node into the linked list. rear 42 7 98 14 null
insertFirst() Be sure to understand what is going on here Accomplish this with an insertFirst() method: public void insertFirst (int id, double dd) { Link newLink = new Link (id,dd); // creates a new object with initial data values. newLink.next = first; // newLink old first // new link now points to what used to be the first link first = newLink; // Now, first points to the newlink we just inserted. first newLink } // end insertFirst() means: ‘links to’ or ‘points to’ or ‘references’ --------------------------------------------------------------------------------------------------------- Let’s look at all the necessary classes and objects… class Link, class LinkedList and class LinkedListApp. (Think of this design like State, StateDriver or StateArr, and the Main app.)
The Link class class Link(Note: this is only the link (node) itself. The object….) { public int iData; // data item public double dData; // data item public Link next; // next link in list note: self-referential // ------------------------------------------------------------- public Link(int id, double dd)// constructor (Note only the data is built here). // Handling next was handled by the client. { iData = id; // initialize data Notice this only dData = dd; // ('next' is automatically set to null) } public void displayLink() // display yourself { System.out.print("{" + iData + ", " + dData + "} "); } } // end class Link (Like an entity class….. It is the data item – has data and pointer to next data…)
The Linked List class LinkList { private Link first; // ref to first link on list public LinkList() // constructor { first = null; // no links on list yet } public boolean isEmpty() // true if list is empty { return (first==null); } public void insertFirst(int id, double dd) // make new link // insert at start of list {Link newLink = new Link(id, dd); // creates new Link with data. newLink.next = first; // newLink --> old first // next pointer in this new links points to null. How can it access next?? first = newLink; // first --> newLink // first now points to this new link } public Link deleteFirst() // deletes first item // (assumes list not empty) {Link temp = first; // save reference to link first = first.next; // delete it: first-->old next return temp; // return deleted link } public void displayList() { System.out.print("List (first-->last): "); // Note: current is a reference to a node. It contains an address! Link current = first; // start at beginning of list //Note: we set up a ‘current’ link which has a value of ‘first’ while(current != null) // until end of list, // As long as current is not = null, there is an additional Link to display. { current.displayLink(); // print data // current is the identity of the ‘current’ link. current = current.next; // move to next link // set new current to the current of the current link for looping. } System.out.println(""); } } // end class LinkList
The Linked List Application (driver…) class LinkListApp { public static void main(String[] args) { LinkList theList = new LinkList(); // make new list; but establishes first link & null. theList.insertFirst(22, 2.99); // insert four items theList.insertFirst(44, 4.99); theList.insertFirst(66, 6.99); SEE NEXT PAGE. theList.insertFirst(88, 8.99); theList.displayList(); // display list while( !theList.isEmpty() ) // until it's empty, { Link aLink = theList.deleteFirst(); // delete link What is aLink? Used for?? System.out.print("Deleted "); // display it aLink.displayLink(); // display the link you “deleted.” System.out.println(""); } theList.displayList(); // display the remaining linked list } // end main() } // end class LinkListApp
Conceptual: Linked List first null 22; 2.99 (This pointer moved to forward pointer (next) in 44 4.99 link) first null 44 4.99 22; 2.99 first null 66; 6.99 44 4.99 22; 2.99
Using Memory Addresses 5A4 first 5A4 null 22; 2.99 (This pointer moved to forward pointer (next) in 44 4.99 link) 5AC 5A4 first 5AC null 5A4 44 4.99 22; 2.99 6B4 5AC 5A4 first 6B4 null 5AC 5A4 66; 6.99 44 4.99 22; 2.99 Sequence of actions below for the links is critical: Allocate new link; fill in data items; Move first to newlink.next. Move address of newLink to first. (The 5A4 represents three hexadecimal digits (12 bits) that symbolizes the last 12 bits of a real 24-bit memory address)
Finding and Deleting Specified Links • Here, we will only add methods to • find() and • delete() specific links.
Add find() routine in LinkList Just adding another method to this object. This method has access to all the instance variables of an object. . . . public Link find(int key) // find link with given key (assumes non-empty list) // start at 'first' { Link current = first; // current is a reference to a Link and points to first. while(current.iData != key) // while no match, { if(current.next == null) // if end of list, didn't find it return null; else // not end of list, go to next link current = current.next; }// end while return current; // found it; returns a pointer to the link. }// end find()
Add delete() routine in LinkList public Link delete(int key) // delete link with given key // (assumes non-empty list) { Link current = first; // search for link Start at head of list. Link previous = first; // Note!! For the delete(), we need to hang on to previous! while(current.iData != key) { if(current.next == null) return null; // didn't find it else { previous = current; // go to next link // Need to save fwd pointer of current cell before current = current.next; // advancing to next one. } // end else } // end while // if we fall through, we’ve found the item to delete. if(current == first) // if first link is the hitright off the bat! first = first.next; // change first // if first link, move fwd link (first.next) to first (value of current) else // otherwise, previous.next = current.next; // bypass it // move fwd link of current link (one to delete) to return current; // fwd link of previous link to bypass link to be deleted. }// end delete() // ------------------------------------------------------------- public void displayList() // display the list //no changes here. Know This! Can you draw this??
Main Application (client) for LinkList class LinkList2App { public static void main(String[] args) { LinkList theList = new LinkList(); // make list theList.insertFirst(22, 2.99); // insert 4 items theList.insertFirst(44, 4.99); theList.insertFirst(66, 6.99); theList.insertFirst(88, 8.99); theList.displayList(); // display list Link f = theList.find(44); // find item Requires an integer argument here in this context.. // Creates a pointer to a link into which the ‘hit’ is moved, if hit is true. if( f != null) System.out.println("Found link with key " + f.iData); // print out data, if good hit. else System.out.println("Can't find link"); Added Link d = theList.delete(66); // delete item // delete returns a reference, as usual. if( d != null ) System.out.println("Deleted link with key " + d.iData); // print out item deleted. else System.out.println("Can't delete link"); theList.displayList(); // display list // After all is said and done, redisplay list. } // end main() } // end class LinkList2App
Pictures for the Soul… ‘Memory Addresses’ Delete: say looking for the link with value of 44.99: 6B4 5AC 5A4 first 6B4 null 5AC 5A4 66; 6.99 44 44.99 22; 2.99 Searching first making 6B4 current; then 5AC current and then, Bingo! We want to delete link at 5AC: 6B4 5AC 5A4 first 6B4 null 5AC 5A4 66; 6.99 44 44.99 22; 2.99 5A4 ALGORITHM: Current = first; Is current.id = search key? If yes, return current (a reference) No. Hold current in previous Move current.next to new current. Loop. Continue until not found or hit. When hit, move current.next to previous.next. Return current to client. Logically deleted link! Link at 5AC is ‘logically deleted.’ “logically deleted?” What does that mean??
Double-Ended Lists (not doubly-linked list) • Actually, I find this more useful in MANY situations. • It allows you to go directly to the end of the list and add a link at the end of the list rather than search the entire list at times to insert at the end… • Note: sometimes inserting at the front is oftentimes NOT what we want to do. • Concept is quite simple: • We have two references: • First • Last • These in turn point to their respective link.
Pictures: 6B4 5AC 5A4 first 6B4 null 5AC 5A4 66; 6.99 44 4.99 22; 2.99 Last 5A4 Equivalently, first null 66; 6.99 44 4.99 22; 2.99 Last Unfortunately, one can still only go ‘forward’ through the linked list… Note: What we have been discussing is called a ‘singly-linked list’ for obvious reasons.
Coding Differences Code for Double-Ended Lists (Changed Methods) class FirstLastList { private Link first; // ref to first link private Link last; // ref to last link// note the extra link // ------------------------------------------------------------- public FirstLastList() // constructor { first = null; // no links on list yet last = null; // must initialize both references to null to begin with. } public boolean isEmpty() // true if no links { return first==null; } public void insertFirst(long dd) // insert at front of list a bit more complicated….. { Link newLink = new Link(dd); // make new link if( isEmpty() ) // if empty list, // no real changes here. last = newLink; // newLink <-- last newLink.next = first; // newLink --> old first first = newLink; // first --> newLink } // ------------------------------------------------------------- public void insertLast(long dd) // insert at end of list // ah, but here are the changes. Additional method. { Link newLink = new Link(dd); // make new link if( isEmpty() ) // if empty list, first = newLink; // first --> newLink ok… and then the statement (ahead) last = newlink; is necessary too. newLink last. else otherwise, last.next = newLink; // old last --> newLink // get last fwd link and have it point to new cell, which is the ‘new’ last; last = newLink; // newLink <-- last // Then, last (up front?) points to the new last cell. } public long deleteFirst() // delete first link { } //no real differentces public void displayList() { // no differences } } // end class FirstLastList
Linked-List Efficiency • Inserting and deleting at beginning of linked-list is fast. • Only need to change a couple of references: O(1) time. • Finding and Deleting or Inserting next to a specific item requires searching (average) half of list which O(n) comparisons. • An array = O(n) comparisons too. • But LL is faster to insert once place is found because nothing needs to be moved (does take time to find, however) • This is significant! (but requires dynamic memory allocation, which means system calls.)\ • A Linked List onlyuses memory it needs. • Can expand as needed. • Arrays are fixed size. • Vectors can help, but usually involve doubling the size of an array that is about to be overfilled and then copying data from the original array into the expanded array.