unit 3: linked lists part 1: introduction to singly linked ... · unit 3: linked lists part 1:...

23
Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering & Applied Science Memorial University of Newfoundland May 30, 2011 ENGI 4892 (MUN) Unit 3, Part 1 May 30, 2011 1 / 23

Upload: others

Post on 17-Jul-2020

14 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

Unit 3: Linked ListsPart 1: Introduction to Singly Linked Lists

Engineering 4892:Data Structures

Faculty of Engineering & Applied ScienceMemorial University of Newfoundland

May 30, 2011

ENGI 4892 (MUN) Unit 3, Part 1 May 30, 2011 1 / 23

Page 2: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

1 Introduction

1 Singly linked lists

1 Insertion

1 Deletion

1 Exceptions

ENGI 4892 (MUN) Unit 3, Part 1 May 30, 2011 2 / 23

Page 3: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

Introduction

We will consider two main kinds of linked structures in this course:linked lists and trees. A linked structure has nodes which store data and alink to another node (or links to other nodes).

Linked lists resolve two of the main problems with arrays:

The size of an array has to be known beforehand to allocate the rightamount of space.

Inserting or deleting items within an array may require other items tobe shifted.

(However, we will see that arrays maintain certain advantages over linkedlists.)

ENGI 4892 (MUN) Unit 3, Part 1 May 30, 2011 3 / 23

Page 4: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

Singly linked lists

Unlike an array, the nodes in a linked structure are not necessarily heldtogether in memory. The structure holds together because the nodes storeaddresses (called links) to other nodes.

All nodes in a singly linked list (SLL) have a single link to the successornode which follows it in the list. The following is an example SLL:

What are these links? Pointers.

Note the slash in the 50-node. This indicates a null pointer and marks theend of the list.

ENGI 4892 (MUN) Unit 3, Part 1 May 30, 2011 4 / 23

Page 5: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

Consider the following class which represents a node used to store an int,

class IntSLLNode {public :

int info ;IntSLLNode ∗next ;IntSLLNode ( int el , IntSLLNode ∗ptr = 0) {

info = el ; next = ptr ;}

} ;

info is the node’s data

The next field stores this node’s link

The constructor initializes both (the link to null if not specified)

ENGI 4892 (MUN) Unit 3, Part 1 May 30, 2011 5 / 23

Page 6: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

How can we create a list like this,

First, generate the node containing 10 and set a pointer-to-node variable p

to point to it,

IntSLLNode ∗p = new IntSLLNode ( 1 0 ) ;

Note that the next field is initialized to null. The node whose next fieldis null is the last node in the list.

To create the node containing 8 we will call new IntSLLNode(8). This willbe the new last node so it is acceptable that its next = 0. How do we linkit to our current list?

p−>next = new IntSLLNode ( 8 ) ;

ENGI 4892 (MUN) Unit 3, Part 1 May 30, 2011 6 / 23

Page 7: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

Finally, how do we add the 50-node,

p−>next−>next = new IntSLLNode ( 5 0 ) ;

Note that the following are all valid pointers to nodes:

p (the first node)

p−>next (the second node)

p−>next−>next (the third node)

This strategy can easily get awkward. What if we want to refer to the100th node?

p−>next−>next−>next−>next−>next−>next ... −>next

Clearly a loop is called for. We define an SLL class for integers whichencapsulates standard operations. This class employs two special pointerscalled head and tail which point to the first and last nodes in the list(respectively).

ENGI 4892 (MUN) Unit 3, Part 1 May 30, 2011 7 / 23

Page 8: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

class IntSLList {public :

IntSLList ( ) {head = tail = 0 ;

}˜IntSLList ( ) ;int isEmpty ( ) {

return head == 0 ;}void addToHead ( int ) ;void addToTail ( int ) ;int deleteFromHead ( ) ; // d e l e t e head , r e t u r n i n f o ;int deleteFromTail ( ) ; // d e l e t e t a i l , r e t u r n i n f o ;void deleteNode ( int ) ;bool isInList ( int ) const ;void printAll ( ) const ;

private :IntSLLNode ∗head , ∗tail ;

} ;

ENGI 4892 (MUN) Unit 3, Part 1 May 30, 2011 8 / 23

Page 9: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

Our previous list would look like this for an IntSLList,

An empty list is represented with both head and tail set to null (althoughit is sufficient to check only head in isEmpty).

We will now consider the various operations of IntSLList in detail:

ENGI 4892 (MUN) Unit 3, Part 1 May 30, 2011 9 / 23

Page 10: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

Insertion

The addToHead method creates a new node at the beginning of the list.This method has to do the following:

Create a new node

Initialize the node’s info field

Set the node’s next field to the current first node

Update head

All four steps are accomplished by the first line of addToHead:

void IntSLList : : addToHead ( int el ) {head = new IntSLLNode (el , head ) ;. . .

}

ENGI 4892 (MUN) Unit 3, Part 1 May 30, 2011 10 / 23

Page 11: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

(code repeated)

void IntSLList : : addToHead ( int el ) {head = new IntSLLNode (el , head ) ;. . .

}

There is one special case to consider. What if the list was previouslyempty. How will tail get set? We have to set it, but only if the list iscurrently empty:

void IntSLList : : addToHead ( int el ) {head = new IntSLLNode (el , head ) ;if ( tail == 0)

tail = head ;}

Note: We have not checked to see whether a new node was properlyallocated from the heap. This check is omitted from IntSLList.

ENGI 4892 (MUN) Unit 3, Part 1 May 30, 2011 11 / 23

Page 12: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

The steps required by addToTail are quite similar. However, we now haveto change two existing pointers: tail, the current last node’s next.

void IntSLList : : addToTail ( int el ) {. . .tail−>next = new IntSLLNode (el ) ;tail = tail−>next ;. . .

}

Special case: Empty list. Must set both head and tail:

void IntSLList : : addToTail ( int el ) {if ( tail != 0) { // i f l i s t not empty ;

tail−>next = new IntSLLNode (el ) ;tail = tail−>next ;

}else head = tail = new IntSLLNode (el ) ;

}

Page 13: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

What is the asymptotic complexity of these two methods?

void IntSLList : : addToHead ( int el ) {head = new IntSLLNode (el , head ) ;if ( tail == 0)

tail = head ;}

void IntSLList : : addToTail ( int el ) {if ( tail != 0) { // i f l i s t not empty ;

tail−>next = new IntSLLNode (el ) ;tail = tail−>next ;

}else head = tail = new IntSLLNode (el ) ;

}

Both are O(1). What would be the complexity of addToTail without thetail pointer? O(n)

ENGI 4892 (MUN) Unit 3, Part 1 May 30, 2011 13 / 23

Page 14: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

Deletion

The deleteFromHead method deletes the first node of the list, and returnsthe value stored at that node. This method has to do the following:

Store the value at the head node in a temporary variable

Store the head node itself in a temporary variable

Update head (and maybe tail)

Delete the former head node

Return the stored value

int IntSLList : : deleteFromHead ( ) {int el = head−>info ;IntSLLNode ∗tmp = head ;. . .head = head−>next ;delete tmp ;return el ;

}

Page 15: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

(code repeated)

int IntSLList : : deleteFromHead ( ) {int el = head−>info ;IntSLLNode ∗tmp = head ;. . .head = head−>next ;delete tmp ;return el ;

}

Special case: What if there is only a single node in the list? This code setshead to null, but it should set tail as well...

int IntSLList : : deleteFromHead ( ) {int el = head−>info ;IntSLLNode ∗tmp = head ;if ( head == tail ) // i f o n l y one node i n t he l i s t

head = tail = 0 ;else head = head−>next ;delete tmp ;return el ;

}

Page 16: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

Special case: What if the list is empty? This is more difficult to handle.What should we return to the user to indicate this problem? We deal withthis by stipulating the following precondition:

// Pre : The l i s t i s not empty .int IntSLList : : deleteFromHead ( ) ;

It would also be a good idea to use an assert statement to ensure thatthe precondition is adhered to,

int IntSLList : : deleteFromHead ( ) {assert ( ! isEmpty ( ) ) ;. . .

But this assert is just a precaution. The user of this SLL should calldeleteFromHead like this,

if ( ! list . isEmpty ( ) )x = list . deleteFromHead ( ) ;

else

// do someth ing e l s e . . .

Page 17: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

Exceptions

Another possibility for the case where deleteFromHead is called on anempty list is to throw an exception.

Throwing an exception (by example)

class DivByZero {public :

string msg ;DivByZero ( string inMsg ) { msg = inMsg ; }

} ;

double safeDivide ( double num , double den ) {if ( den == 0)

throw DivByZero ("Division by zero in safeDivide" ) ;return num / den ;

}

If den == 0 the function will construct an instance of DivByZero andterminate, throwing this object up to the caller. The return statement willnot be reached.

Page 18: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

Exception handling

void foo ( ) {safeDivide ( 3 , 0 ) ;

}

void bar ( ) {try {

foo ( ) ;} catch ( DivByZero &exception ) {

cerr << "Exception: " << exception . msg << endl ;}

}

int main ( int argc , char ∗∗argv ) {bar ( ) ;return 0 ;

}

Clearly foo will cause the exception to be thrown. However, the exceptionis caught in bar. The object created in the throw statement can beinspected here.

Page 19: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

Notes on exceptions

If left uncaught an exception will propagate all the way up to the user. Ifthe try and catch statements are removed from bar the exception will getthrown up to main and then actually terminate the program with themessage:

terminate called after throwing an instance of ’DivByZero’

(or similar)

The idea of exceptions in C++ is to allow a problem (i.e. an exception) tobe handled at the appropriate level. For example, deleteFromHead cannotdeal with an empty list. However, if deleteFromHead was modified tothrow an exception, the calling code might be in the position to catch theexception and choose some appropriate course of action.

Note that there are different theories as to how exceptions should be used.Most people advocate using them only for very exceptional circumstances(trying to delete from an empty list probably doesn’t qualify).

Page 20: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

Consider, deleteFromTail. The idea of this function is similar todeleteFromHead but there are additional complications. The followingtasks must be accomplished:

Store the value of the current last node

Find the predecessor of the current last node

Delete the current last node

Update tail

Update the new last node

Return the stored value

The problem is the second step. We must find the node whose next

pointer equals tail.

for ( tmp = head ; tmp−>next != tail ; tmp = tmp−>next ) ;

Page 21: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

We can now proceed with deleteFromTail,

int IntSLList : : deleteFromtail ( ) {int el = tail−>info ;. . .IntSLLNode ∗tmp ; // The p r e d e c e s s o r o f t a i lfor ( tmp = head ; tmp−>next != tail ; tmp = tmp−>next ) ;delete tail ;tail = tmp ;tail−>next = 0 ;. . .return el ;

}

Special Cases:

The list is empty. Same problem as for deleteFromHead. We employthe same solution (i.e. add a precondition in the documentation andan assert statement to check it in the code).

There is just one node in the list. The predessor search above will notwork! Also, we will now need to modify head.

Page 22: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

Final version:

int IntSLList : : deleteFromTail ( ) {assert ( ! isEmpty ( ) ) ;int el = tail−>info ;if ( head == tail ) { // i f o n l y one node i n l i s t

delete head ;head = tail = 0 ;

}else { // more than one node

IntSLLNode ∗tmp ; // the p r e d e c e s s o r o f t a i lfor ( tmp = head ; tmp−>next != tail ;

tmp = tmp−>next ) ;delete tail ;tail = tmp ; // p r e d e c e s s o r o f t a i l becomes t a i ltail−>next = 0 ;

}return el ;

}

Page 23: Unit 3: Linked Lists Part 1: Introduction to Singly Linked ... · Unit 3: Linked Lists Part 1: Introduction to Singly Linked Lists Engineering 4892: Data Structures Faculty of Engineering

What is the asymptotic complexity of these two methods?

deleteFromHead involves no loops, just the manipulation of a few pointers:O(1)

deleteFromTail does have a loop. The body of this loop is entered n − 1times. Hence, deleteFromTail is O(n).

ENGI 4892 (MUN) Unit 3, Part 1 May 30, 2011 23 / 23