An Introduction to Programming and Object Oriented Design

An Introduction to Programming and Object Oriented Design using Java 2 nd Edition. May 2004 Jaime Niño Frederick Hosch Chapter 20 Implementing lists : Linked implementations

Objectives ñ After studying this chapter you should understand the following: ñ the design and structure of linked list implementations; ñ variations in designs for linked lists, including doubly linked lists; ñ advantages and disadvantages of linked vs. array-based implementations. ñ Also, you should be able to: ñ write algorithms for linked-based structures; ñ define classes implemented with linked-based structures. May 2004 NH-Chapter 20 1

Linked implementations ñ Structure built from collection of nodes that reference each other. ñ A node ñ contains reference to a list element, ñ one or more variables referencing other structure nodes. May 2004 NH-Chapter 20 2

First linked implementation ñ Linked. List: Each node references node containing next list element. node A May 2004 B NH-Chapter 20 C D 3

Class Node ñ Class Node, local to Linked. List, models nodes. ñ Node structure: ñ must know an element of the List, ñ must know the next Node in sequence. ñ As local class of Linked. List has no methods. May 2004 NH-Chapter 20 4

Class Node implementation public class Linked. List<Element> extends Abstract. List<Element> { … private class Node { private Element element; private Node next; // Create a Node containing specified element. public Node (Element element) { this. element = element; this. next = null; } } // end of class Node } // end of class Linked. List May 2004 NH-Chapter 20 5

Linked. List implementation public class Linked. List<Element> extends Abstract. List<Element> { private int size; private Node first; // Create an empty Linked. List<Element>. public Linked. List () { size = 0; first = null; } … } May 2004 NH-Chapter 20 6

An empty linked list May 2004 NH-Chapter 20 7

Linked list with three entries May 2004 NH-Chapter 20 8

Method to get the i-th node /** * The i-th node of this Linked. List. * The Linked. List must be non-empty. * require 0 <= i && i < this. size() */ private Node get. Node (int i) { Node p = first; int pos = 0; // p is pos-th Node while (pos != i) { p = p. next; pos = pos + 1; } return p; } May 2004 NH-Chapter 20 9

Method to get the i-th node : i == 2 pos Linked. List size 4 first p Node next element May 2004 0 Node next É element Node next É NH-Chapter 20 element next É element É 10

Method to get the i-th node : i == 2 pos Linked. List size 4 first p Node next element May 2004 1 Node next É element Node next É NH-Chapter 20 element next É element É 11

Method to get the i-th node : i == 2 pos Linked. List size 4 first p Node next element May 2004 2 Node next É element Node next É NH-Chapter 20 element next É element É 12

Implementing Linked. List methods public Element get (int index) { Node p = get. Node(index); return p. element; } ñNote: method get ñ uses get. Node ñ get(i) will take i+1 steps to get the element. May 2004 NH-Chapter 20 13

Method remove(int) ñ Given an index referencing a node to be removed: ñ Find previous node referencing it. ñ Update that node’s next. May 2004 NH-Chapter 20 14

Method remove(int) ñFind previous node. Linked. List size Element to be removed 4 first Node next element May 2004 Node next É element Node next É NH-Chapter 20 element next É element É 15

Method remove(int) Linked. List size Element to be removed 4 first p Node next element May 2004 Node next É element Node next É NH-Chapter 20 element next É element É 16

Method remove(int) Linked. List size Element to be removed 4 first p Node next element May 2004 Node next É element Node next É NH-Chapter 20 element next É element É 17

Method remove(int) Linked. List size Element to be removed 4 first p Node next element Node next É element É Copy May 2004 NH-Chapter 20 18

Method remove(int) Linked. List size Element to be removed 4 first p Node next element May 2004 Node next É element Node next É NH-Chapter 20 element next É element É 19

Method remove(int) Linked. List size Element to be removed 3 first p Node next element May 2004 Node next É element Node next É NH-Chapter 20 element next É element É 20

Method remove(int), special case ñ Recall get. Node requires argument >= 0. ñ If index is 0, it’s not legal to write Node p = get. Node(index-1); ñ Special case: index 0 removes first linked element. ñ instance variable first of Linked. List must be modified. May 2004 NH-Chapter 20 21

Method remove(int) Linked. List size 4 node to be removed first Node next element May 2004 Node next É element Node next É NH-Chapter 20 element next É element É 22

Method remove(int) Linked. List size 4 node to be removed first Node next element Node next É element É copy May 2004 NH-Chapter 20 23

Method remove(int) Linked. List size 4 node to be removed first Node next element May 2004 Node next É element Node next É NH-Chapter 20 element next É element É 24

Method remove(int) Linked. List size 3 node to be removed first Node next element May 2004 Node next É element Node next É NH-Chapter 20 element next É element É 25

Implementation of remove(int) public void remove (int index) { if (index == 0) first = first. next; else { Node p = get. Node(index-1); p. next = p. next; } size = size - 1; } May 2004 NH-Chapter 20 26

Method add (int, Element) ñ To add an element at the i-th position ñ must find the element with index i-1 ñ special case to consider when i is 0. May 2004 NH-Chapter 20 27

Method add(int, Element) ñAdd an element at index 2. ñMust find previous node. Node Linked. List size next element É 4 first Node Element to add Node next element É May 2004 NH-Chapter 20 28

Method add(int, Element) Node Linked. List size next element É 4 first p Node Element to add Node next element É May 2004 NH-Chapter 20 29

Method add(int, Element) ñNew node next is p’s next Node Linked. List size next element É 4 first p Node Element to add Node next element É May 2004 NH-Chapter 20 30

Method add(int, Element) ñp node next is new node Node Linked. List size next element É 4 first p Node Element to add Node next element É May 2004 NH-Chapter 20 31

Method add(int, Element) ñLinked. List size is incremented. Node Linked. List size next element É 5 first p Node Element to add Node next element É May 2004 NH-Chapter 20 32

Method add(int, Element) ñadd at index 0 Node Linked. List size next element É 4 first Node Element to add Node next element É May 2004 NH-Chapter 20 33

Method add(int, Element) ñadd at index 0 Node Linked. List size next element É 4 first Node Element to add Node next element É May 2004 NH-Chapter 20 34

Method add(int, Element) ñadd at index 0 Node Linked. List size next element É 5 first Node Element to add Node next element É May 2004 NH-Chapter 20 35

Method add (int, Element) public void add (int index, Element element) { Node new. Node = new Node(element); if (index == 0) { new. Node. next = first; first = new. Node; } else { Node p = get. Node(index-1); new. Node. next = p. next; p. next = new. Node; } size = size + 1; } May 2004 NH-Chapter 20 36

Linked list variations ñ Adding a reference to last node makes adding to end of list constant. May 2004 NH-Chapter 20 37

Linked. List: adding a last reference ñ Creates special cases in other methods. For instance, remove public void remove (int index) { if (size == 1) { // remove only element first = null; last = null; }else if (index == 0) {//remove first element first = first. next; }else { Node p = get. Node(index-1); p. next = p. next; if (index == size-1) //last element removed last = p; } size = size - 1; } May 2004 NH-Chapter 20 38

Header nodes ñ “dummy” node ñ Always present at front of list, ñ contains no element, ñ first always references header node, ñ first is never null. ñ Reduces special cases in the implementation of some methods. May 2004 NH-Chapter 20 39

Header nodes May 2004 NH-Chapter 20 40

Circular lists ñ Last node references the first. May 2004 NH-Chapter 20 41

Doubly-linked lists May 2004 NH-Chapter 20 42

Doubly-linked list constructor ñ Assuming Header extends Node Doubly. Linked. List constructor creates header Node, and links it to itself. public Doubly. Linked. List () { size = 0; header = new Header(); header. next = header; header. previous = header; } May 2004 NH-Chapter 20 43

Doubly-linked list constructor May 2004 NH-Chapter 20 44

Doubly-linked lists: add(Element) Header A B C New May 2004 NH-Chapter 20 45

Doubly-linked lists: add(Element) z new node previous is node C Header A B C New May 2004 NH-Chapter 20 46

Doubly-linked lists: add(Element) znew node next is header Header A B C New May 2004 NH-Chapter 20 47

Doubly-linked lists: add(Element) z Header previous is new node Header A B C New May 2004 NH-Chapter 20 48

Doubly-linked lists: add(Element) z C node next is new node Header A B C New May 2004 NH-Chapter 20 49

Doubly-linked lists: remove(1) May 2004 NH-Chapter 20 50

Doubly-linked lists: remove(1) Header May 2004 A B NH-Chapter 20 C 51

Doubly-linked lists: remove(1) Header May 2004 A B NH-Chapter 20 C 52

Linked Lists limitations ñ Element access by index is linear. ñ Would not use a linked implementation if primary operation is to access randomly by index. ñ Method get uses get. Node: requires i steps to get Node with index i. May 2004 NH-Chapter 20 53

Linked Lists limitations: index. Of(Element) ñ index. Of uses method get. ñ If element not found, get executes n times, with index values 0 through n-1: value of i: 0 1 2 … n-1 steps of get(i): 0 1 2 … n-1 ñ Steps require: 0 + 1 + 2 + … + (n-1) = (n 2 -n)/2. ñ Method is quadratic. May 2004 NH-Chapter 20 54

Re-implementation of index. Of public int index. Of (Element element) { Node p = first; int pos = 0; while (p != null && !element. equals(p. element)) { p = p. next; pos = pos+1; } if (p == null) return -1; else return pos; } ñ Method is linear. ñ But uses private members of the class Linked. List. May 2004 NH-Chapter 20 55

Dynamic memory allocation ñ Recall memory space for method variables – parameters and local variables – is allocated when the method is invoked, and reclaimed (“deallocated”) when the method completes. ñ This is called automatic allocation and deallocation. ñ Space for an object’s instance variables is allocated when the object is created. This is sometimes called dynamic allocation. May 2004 NH-Chapter 20 56

Dynamic memory allocation ñ In an array-based list implementation, memory space for the array elements is allocated when the array is created. ñ In a linked implementation, space required for a node is allocated when the node is created, i. e. when an item is added to the list. ñ But when is this space deallocated? May 2004 NH-Chapter 20 57

Dynamic memory allocation ñ The Java run-time system implements a facility called garbage collection. ñ Dynamically allocated space that can no longer be accessed is termed garbage. ñ If we create an object and then lose all references to the object, the memory space occupied by the object becomes garbage. ñ The run-time system continuously looks for garbage and reclaims the space – “collects the garbage. ” May 2004 NH-Chapter 20 58

Dynamic memory allocation ñ Many programming languages do not include garbage collection as part of their run-time systems. ñ These languages require programs to explicitly deallocate dynamically allocated space. ñ Problem: difficult to know when an object is no longer accessible and can be safely deallocated. ñ Subtle errors ñ Memory leaks: garbage not being recognized and reclaimed ñ Dangling reference: space still accessible being mistakenly reclaimed as garbage. May 2004 NH-Chapter 20 59

Summary ñ With linked structures, structural relationships between objects in a container are explicitly modeled by references between nodes that contain the objects. ñ Covered several approaches to implementing lists with linked structures. ñ In the simplest approach, each node contains an element of the list and references the node containing the next element. ñ addition of a header node simplifies the implementation by eliminating some of the special cases that must otherwise be handled explicitly. May 2004 NH-Chapter 20 60

Summary ñ Considered several variations including a doubly-linked circular list with header. ñ In this structure, each node references both the preceding and the following node. ñ The structure is circular: the header follows the last node in the list, and the last node in the list precedes the header. May 2004 NH-Chapter 20 61

Summary ñ One shortcoming of linked list implementations ñ get, remove, and add are all linear. ñ In each case, we must start at the beginning of the list and traverse the list to locate the node with a particular index. ñ This becomes a problem when we need to iteratively examine each element of a list. May 2004 NH-Chapter 20 62

Summary ñ Considered dynamic storage allocation. ñ In Java, the run-time system recognizes when an object is no longer accessible and reclaims the storage space used by that object. ñ This mechanism is called garbage collection. ñ In some programming languages, the application must explicitly free storage space that is no longer needed. ñ This can lead to subtle errors in a program. ñ space might be inaccessible without being explicitly freed; ñ space might be freed which it is still accessible. May 2004 NH-Chapter 20 63
- Slides: 64