180 likes | 398 Views
Singly Linked Lists. Singly Linked Lists: Introduction. Singly Linked Lists: Implementation. Singly Linked Lists: Analysis. Singly Linked Lists: Creation and Destruction. Singly Linked Lists: Accessor Methods. Singly Linked Lists: Mutator Methods. next. datum. a). slist. head. slist.
E N D
Singly Linked Lists • Singly Linked Lists: Introduction. • Singly Linked Lists: Implementation. • Singly Linked Lists: Analysis. • Singly Linked Lists: Creation and Destruction. • Singly Linked Lists: Accessor Methods. • Singly Linked Lists: Mutator Methods.
next datum a) slist head slist head slist slist b) tail c) head sentinel tail d) Introduction • The singly-linked list is the most basic of all the linked data structures. Circular Singly Linked Lists
a) c) head sentinel head head d) b) tail tail Empty Singly Linked Lists
Integer slist head datum datum 12 next next tail Integer datum -4 next Integer 15 Singly Linked Lists: Implementation • The Figure below illustrates the Singly Linked List scheme we have chosen to implement.
Singly Linked Lists: Implementation (Contd.) • The classes MyLinkedList and MyLinkedList.Element are shown in the code below. Element class defines the list node. 1 public class MyLinkedList { 2 protected Element head; 3 protected Element tail; 4 public final class Element { 5 Object datum; 6 Element next; 7 Element(Object datum, Element next) { 8 this.datum = datum; 9 this.next = next; 10 } // End of Element() constructor
Singly Linked Lists: Implementation (Contd.) • The inner class MyLinkedList.Element has some accessor methods such as: 11 public Object getDatum() \{ 12 return datum; 13 } // End of getDatum() method 14 15 public Element getNext() \{ 16 return next; 17 } // End of getNext() method 18 // Other Element Methods... 19 } // End of inner class Element 20 // Other MyLinkedList Methods... 21 } // End of class MyLinkedList
Singly Linked Lists: Space Analysis • Now, we can take a look at the space requirements: S(n) = sizeof(MyLinkedList) + n sizeof(MyLinkedList.Element) = 2 sizeof(MyLinkedList.Element ref) + n [sizeof(Object ref) + sizeof(MyLinkedList.Element ref)] = (n + 2) sizeof(MyLinkedList.Element ref) + n sizeof(Object ref)
Singly Linked Lists: Complexity Analysis • The constructor of the inner class MyLinkedList.Element performs 2 Operations. • It has then a constant complexity of O(1). • To access the class fields, each of the two methods: getDatum() and getNext() performs 1 Operation. • In this case, both methods, getDatum() and getNext(), have a constant complexity of O(1). • The constructor of MyLinkedList class has an empty implementation! • Regardless of this, its running time is clearly constant, i.e., O(1).
head slist 3 3 slist slist head head head head head head head head head tail 11 11 tail tail tail tail tail tail tail tail tail -1 -1 3 slist 11 -1 Singly Linked Lists: Creation and Destruction • The following code fragment creates a new singly linked lists. MyLinkedList slist = new MyLinkedList(); • Destroying (or purging) an existing list is quite easy! slist.purge(); 1 public void purge(){ 2 head = null; 3 tail = null; 4 } // End of purge()method 1) Linked List [slist] 3) Finally! 2)slist.Purge() Garbage! • It is easy to assume that the running time of the method purge() is O(1). • However, the exact running time cannot be estimated!!!
Accessor Methods of MyLinkedList Class • The accessor methods of MyLinkedList class are defined below: 1 public Element getHead() { 2 return head; 3 } // End of getHead() method 4 5 public Element getTail() { 6 return tail; 7 } // End of getTail() method 8 9 public boolean isEmpty() { 10 return head == null; • } // End of isEmpty() method 12 public Object getFirst() throws ListEmptyException { 13 if(head == null) 14 throw new ListEmptyException(); 15 return head.datum; 16 } // End of getFirst() method 17 18 public Object getLast() throws ListEmptyException { 19 if(head == null) 20 throw new ListEmptyException(); 21 return tail.datum; 22 } // End of getLast() method
Mutator Methods of MyLinkedList Class • The mutator methods of MyLinkedList class are defined below: 1 public void prepend(Object item) { 2 Element tmp = new Element(item, head); 3 if(head == null) 4 tail = tmp; 5 head = tmp; 6 } // End of prepend() method 7 public void append(Object item) { 8 Element tmp = new Element(item, null); 9 if(head == null) 10 head = tmp; 11 else 12 tail.next = tmp; 13 tail = tmp; 14 } // End of append() method 15 public void assign(MyLinkedList slist) { 16 if(slist != this) { 17 purge(); 18 for(Element tmp = slist.head; tmp != null; tmp = tmp.next) 19 append(tmp.datum); 20 } // End of the if block 21 } // End of assign() method Question: What will happen if we don’t check the list’s refrences befor performing the list assignment?
Mutator Methods of MyLinkedList Class (Contd.) 22 public void extract(Object item) throws IllegalArgumentException { 23 Element ptr = head; 24 Element prevPtr = null; 25 while(ptr != null && ptr.datum != item) { 26 prevPtr = ptr; 27 ptr = ptr.next; 28 } // End of while block 29 if(ptr == null) 30 throw new IllegalArgumentException (“Item not in the list! "); 31 if(ptr == head) 32 head = ptr.next; 33 else 34 prevPtr.next = ptr.next; 35 if(ptr == tail) 36 tail = prevPtr; 37 } // End of extract() method
Mutator Methods of Element Class • Now, let’s consider the methods insertAfter() and insertBefore() of MyLinkedList.Element class shown below. 1 public void insertAfter(Object item) { 2 next = new Element(item, next); 3 if(tail == this) 4 tail = next; 5 } // End of insertAfter() method 6 public void insertBefore(Object item) { 7 Element tmp = new Element(item, this); 8 if(this == head) 9 head = tmp; 10 else { 11 Element prevPtr = head; 12 while(prevPtr != null && prevPtr.next != this) 13 prevPtr = prevPtr.next; 14 prevPtr.next = tmp; 15 } // End of else block 16 } // End of insertBefore() method
Drill Questions • Let's consider the redefinition of the assign() method shown below: 1 public void assign(MyLinkedList slist) { 2 purge(); 4 for(Element tmp = slist.head; tmp != null; tmp = tmp.next) 5 append(tmp.datum); 6 } // End of assign() What are the possible problems with such an implementations? • The method extract() as defined in this session needs some modifications to work correctly in all situations. Provide your own implementation for this method. • Which methods are affected if we do not use the tail reference in MyLinkedList class.