Singly Linked Lists Singly Linked Lists: Introduction. Singly Linked Lists: Implementation. Singly...

Preview:

Citation preview

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.

Introduction

• The singly-linked list is the most basic of all the linked data structures. datum next

slist head a)

slist head

tail

b)

sentinel

slist head c)

slist tail d)

Circular Singly Linked Lists

Empty Singly Linked Lists

head

a)

b)

head

tail

d)

tail

sentinelhead

c)

Singly Linked Lists: Implementation

• The Figure below illustrates the Singly Linked List scheme we have chosen to implement.

slist head

tail

datum

next

12

-4

15

datum

next

datum

next

Integer

Integer

Integer

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)

Space RequireExplanation

sizeof)MyLinkedList)

The list reference has two fields:

head )type: Element) and tail )type: Element)

= 2 sizeof)MyLinkedList.Element ref)

n

sizeof)MyLinkedList.Element)

The list has n elements of type Element. Each element has two fields-- datum )type Object) and next )type Element).

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).

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();

head

tail

slist

1 public void purge(){2 head = null;3 tail = null;4 } // End of purge()method

slist headtail head

tail headtail

311

-1

slist headtail head

tail headtail

311

-1

slist headtail head

tail headtail

311

-1

1) Linked List [slist]

2(slist.Purge()3) Finally!

• It is easy to assume that the running time of the method purge() is O(1).• However, the exact running time cannot be estimated!!!

Garbage!

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 45 public Element getTail() {6 return tail;7 } // End of getTail() method 89 public boolean isEmpty() {10 return head == null;11 } // End of isEmpty() method12 public Object getFirst() throws ListEmptyException {13 if(head == null)14 throw new ListEmptyException();15 return head.datum;16 } // End of getFirst() method 1718 public Object getLast() throws ListEmptyException {19 if(head == null) 20 throw new ListEmptyException();21 return tail.datum;22 } // End of getLast() method

Method Name# of Operationcomplexity

getHead))1 OperationO)1)

getTail))1 OperationO)1)

isEmpty))1 OperationO)1)

getFirst))1 OperationO)1)

getLast))1 OperationO)1)

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() method7 public void append(Object item) {8 Element tmp = new Element(item, null);9 if(head == null)10 head = tmp;11 else12 tail.next = tmp;13 tail = tmp; 14 } // End of append() method15 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 block21 } // 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 block29 if(ptr == null)30 throw new IllegalArgumentException (“Item not in the list! ");31 if(ptr == head)32 head = ptr.next;33 else34 prevPtr.next = ptr.next;35 if(ptr == tail)36 tail = prevPtr;37 } // End of extract() method

Mutator NameComplexity

prepend))O)1)

append))O)1)

assign))O)n)

extract))O)n)

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

Mutator NameComplexity

insertAfter))O)1)

insertBefor))O)n)

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.

Recommended