160 likes | 277 Views
COP 3538 Data Structures with OOP. Chapter 5 - Part 3 Linked Lists Doubly-Linked Lists. Doubly Linked Lists. How do we track in singly-linked lists? Sequence: previous = current; current = current.next; Always keep ‘last’ link for insert() and delete(), etc…
E N D
COP 3538 Data Structures with OOP Chapter 5 - Part 3 Linked Lists Doubly-Linked Lists
Doubly Linked Lists • How do we track in singly-linked lists? Sequence: previous = current; current = current.next; • Always keep ‘last’ link for insert() and delete(), etc… • So far: a given link has its data and a forward link! • Many applications require both forward and rearward traversal of a linked list. • To do this, each link (node) has both forward and rearward (backward) links (pointers). • So, if we are ‘at’ a given link, can go in either way.
Consider: Code for class Link class Link { public long dData; // data item (// other instance data for this object as required.) public Link next; //next link in list (forward) public Link previous; //previous link in list (back) } Downside: each time you insert() a link, one MUST account for twopointers: one to the next link and one to the rear link. Inserting and Deleting can be complicated. One MUST keep track of the links and change them in a prescribed order (we shall see).
Conceptual: Doubly-Linked List Note: Here we are using an insertFirst() method. first null 22; 2.99 null first null 44 4.99 22; 2.99 null first null 66; 6.99 44 4.99 22; 2.99 null These may also be double-ended too (not shown) (Can start at both the beginning and end of the linked list.
Using Memory Addresses – Doubly-Linked List 5A4 First: we will insert new link at front of list. Allocated link (newLink) is ‘at’ 5AC. first 5A4 null Null 22; 2.99 Next, we inserted a new first link. We used insertFirst() method. 5AC 5A4 first 5AC null null 5A4 44 4.99 22; 2.99 5AC Now insert another link where indicated. The link itself is at 6B8 We used an insertAfter() method.. 5AC 6B8 5A4 first 5AC null 6B8 5AC 5A4 44 4.99 33 3.99 null 6B8 22; 2.99 First: find out where the link should be located in list. Search to find. Found. Sequence is important!Fill in links in the new cell first! Remember, you are pointing at 5A4 when you start. So, you have all necessary addresses to do job. To add the links to 6B8, we had to move forward link of 5AC to forward link of 6B8 and backward link of 5A4 to the backward link of 6B8 (the new node). New node is now done. Next, change the forward link in 5AC (which was 5A4) to point to the new link at 6B8, and change backward link in 5A4 (which was 5AC) to point to the new link 6B8. (Four links are involved; two in new node and two changes)
Inserting into a Doubly-Linked list. • Now, as shown, one may need to insert ‘before’ or insert ‘after’ a link somewhere in the list; • Also, one may have to insert at the ‘beginning’ of list or the ‘end’ of the list. • You will almost always have to search to discover where you will insert a new link. • If you are inserting at the beginning or end, insertFirst() and insertLast() are easy. To insert elsewhere (assumes links are ‘ordered’), you will have to search to determine the correct location.
Deleting a link from a Doubly-Linked list • Must search forlink to be deleted. • Code for Boundary Conditions: • May be at front of list • May be last link of list • May be in between • May be notfound. • Code for Expected Condition: May be in the middle somewhere in linked list. • Code for the Boundary Conditions. • Your code must account for all of these!
Deletion in a doubly-linked list Let’s delete this link. 5AC 6B8 5A4 first 6B4 null 6B8 5AC 5A4 44 4.99 33 3.99 null 6B8 22; 2.99 To remove 6B8, Move the forward link in 6B8 (which is 5A4) to the forward link at 5AC. Move the rearward link of 6B8 (which is 5AC) to the rearward link of 5A4 You have ‘delinked’ the node to be deleted. 5AC 6B8 5A4 Yields:the graphic: Note: there is noforward or backward link to 6B8… null 6B8 5AC 5A4 44 4.99 33 3.99 null 6B8 22; 2.99 5A4 5AC
Consider: Code for class Link class Link { public long dData; // data item public <whatever additional attributes your app requires> public Link next; // next link in list public Link previous; // previous link in list // ------------------------------------------------------------- public Link(long d) // constructor; initializes attributes… { dData = d; } // end constructor // ------------------------------------------------------------- public void displayLink() // display this link { System.out.print(dData + " "); } // probably uses a toString… // ------------------------------------------------------------- } // end class Link
class DoublyLinkedList { private Link first; // ref to first item private Link last; // ref to last item public DoublyLinkedList() // constructor HERE’S YOUR LINKED LIST. WORKER OBJECT !! { NOTE WHERE THE LINKED LIST IS CREATED! first = null; // no items on list yet NOTE: NO ‘ARRAY’ OF OBJECTS. WHY??? last = null; } public boolean isEmpty() // true if no links { return first==null; } public void insertFirst(long dd) { // if insert at front of list. NO SEARCH!! Link newLink = new Link(dd); // make new linkGo through this! if( isEmpty() ) // if empty list, last = newLink; // (Points to end of list, which is new node: newLink) else { first.previous = newLink; // newLink.next = first; // (Points to next link) } first = newLink; // (Points to start of Linked List) }// end insertFirst() public void insertLast(long dd) { // insert at end of list NO SEARCH!!!! Link newLink = new Link(dd); // make new link if( isEmpty() ) // if empty list, first = newLink; // first --> newLink else { last.next = newLink; // old last --> newLink Draw these or at least go through these! newLink.previous = last; // old last <-- newLink We will go through this… } last = newLink; // newLink <-- last }// ------------------------------------------------------------- 1 of 5
2 of 5 public Link deleteFirst() // delete first link { // (assumes non-empty list) Link temp = first; // will return temp to calling environment. See header returns a Link… if(first.next == null) // if only one item last = null; // null <-- last Go through this logic else first.next.previous = null; // null <-- old next first = first.next; // first --> old next return temp; } public Link deleteLast() // delete last link { // (assumes non-empty list) Link temp = last; if(first.next == null) // if only one item first = null; // first --> null else last.previous.next = null; // old previous --> null last = last.previous; // old previous <-- last return temp; } // -------------------------------------------------------------
3 of 5 public boolean insertAfter(long key, long dd) { // (assumes non-empty list) Link current = first; // start at beginning while(current.dData != key) // until match is found, Must search to find correct ‘spot’ { current = current.next; // move to next link if(current == null) return false; // didn't find it } // end while() GO THROUGH THIS ONE, IF TIME. Link newLink = new Link(dd); // make new link if(current==last) // if last link, means node we want to add will be ‘new’ last… { newLink.next = null; // newLink --> null last = newLink; // newLink <-- last } else // not last link, { newLink.next = current.next; // newLink --> old next Can you DRAW these????? // newLink <-- old next current.next.previous = newLink; ==================== } newLink.previous = current; // old current <-- newLink current.next = newLink; // old current --> newLink return true; // found it, did insertion }
4 of 5 public Link deleteKey(long key) // delete item w/ given key { // (assumes non-empty list) Link current = first; // start at beginning while(current.dData != key) // until match is found, Must find the node in order to delete it. { current = current.next; // move to next link if(current == null) return null; // didn't find it } if(current==first) // found it; first item? first = current.next; // first --> old next else // not first // old previous --> old next current.previous.next = current.next; ======== if(current==last) // last item? last = current.previous; // old previous <-- last else // not last // old previous <-- old next current.next.previous = current.previous; ======= return current; // return value }
5 of 5 // ------------------------------------------------------------- public void displayForward() { System.out.print("List (first-->last): "); Link current = first; // start at beginning while(current != null) // until end of list, { current.displayLink(); // display data current = current.next; // move to next link } System.out.println(""); } // ------------------------------------------------------------- public void displayBackward() { System.out.print("List (last-->first): "); Link current = last; // start at end while(current != null) // until start of list, { current.displayLink(); // display data current = current.previous; // move to previous link } System.out.println(""); } // ------------------------------------------------------------- } // end class DoublyLinkedList
class DoublyLinkedApp { public static void main(String[] args) { // make a new list DoublyLinkedList theList = new DoublyLinkedList(); theList.insertFirst(22); // insert at front theList.insertFirst(44); theList.insertFirst(66); theList.insertLast(11); // insert at rear theList.insertLast(33); theList.insertLast(55); theList.displayForward(); // display list forward theList.displayBackward(); // display list backward theList.deleteFirst(); // delete first item theList.deleteLast(); // delete last item theList.deleteKey(11); // delete item with key 11 theList.displayForward(); // display list forward theList.insertAfter(22, 77); // insert 77 after 22 theList.insertAfter(33, 88); // insert 88 after 33 theList.displayForward(); // display list forward } // end main() } // end class DoublyLinkedApp
PLEASE NOTE THAT MY APPROACH IMPLIES THAT YOU KEEP YOUR LINKED LIST ORDERED. THIS IMPLIES YOU ‘SEARCH’ TO FIND THE PROPER PLACE TO ADD OR DELETE A LINK.