Linked Lists A linked data structure consists of

  • Slides: 52
Download presentation
Linked Lists • A linked data structure consists of capsules of data known as

Linked Lists • A linked data structure consists of capsules of data known as nodes that are connected via links – Links can be viewed as arrows and thought of as one way passages from one node to another • In Java, nodes are realized as objects of a node class • The data in a node is stored via instance variables • The links are realized as instance variables holding references (variables holding references to objects of node class) – A reference is a memory address, and is stored in a variable of a class type – Therefore, a link is an instance variable of the node class type itself • A linked list consists of a single chain of nodes, each connected to the next by a link – The first node is called the head node – The last node serves as a kind of end marker CS 102 Algorithms and Programming II 1

Nodes and Links in a Linked List CS 102 Algorithms and Programming II 2

Nodes and Links in a Linked List CS 102 Algorithms and Programming II 2

A Simple Linked List Class • In a linked list, each node is an

A Simple Linked List Class • In a linked list, each node is an object of a node class – Note that each node is typically illustrated as a box containing one or more pieces of data • Each node contains data and a link to another node – A piece of data is stored as an instance variable of the node – Data is represented as information contained within the node "box" – Links are implemented as references to a node stored in an instance variable of the node type – Links are typically illustrated as arrows that point to the node to which they "link" CS 102 Algorithms and Programming II 3

A Node Class public class Node 1 { private String item; private int count;

A Node Class public class Node 1 { private String item; private int count; private Node 1 link; public Node 1( ) { link = null; item = null; count = 0; } public Node 1(String new. Item, int new. Count, Node 1 link. Value) { set. Data(new. Item, new. Count); link = link. Value; } CS 102 Algorithms and Programming II 4

A Node Class public void set. Data(String new. Item, int new. Count) { item

A Node Class public void set. Data(String new. Item, int new. Count) { item = new. Item; count = new. Count; } public void set. Link(Node 1 new. Link) { link = new. Link; } public String get. Item( ) { return item; } public int get. Count( ) { return count; } public Node 1 get. Link( ) { return link; } } CS 102 Algorithms and Programming II 5

A Simple Linked List Class • The first node, or start node in a

A Simple Linked List Class • The first node, or start node in a linked list is called the head node – The entire linked list can be traversed by starting at the head node and visiting each node exactly once • There is typically a variable of the node type (e. g. , head) that contains a reference to the first node in the linked list – However, it is not the head node, nor is it even a node – It simply contains a reference to the head node • A linked list object contains the variable head as an instance variable of the class • A linked list object does not contain all the nodes in the linked list directly – Rather, it uses the instance variable head to locate the head node of the list – The head node and every node of the list contain a link instance variable that provides a reference to the next node in the list – Therefore, once the head node can be reached, then every other node in the list can be reached CS 102 Algorithms and Programming II 6

An Empty List is Indicated by null • The head instance variable contains a

An Empty List is Indicated by null • The head instance variable contains a reference to the first node in the linked list – If the list is empty, this instance variable is set to null – Note: This is tested using ==, not the equals method • The linked list constructor sets the head instance variable to null – This indicates that the newly created linked list is empty • The last node in a linked list should have its link instance variable set to null – That way the code can test whether or not a node is the last node – Note: This is tested using ==, not the equals method CS 102 Algorithms and Programming II 7

A Linked List Class public class Linked. List 1 { private Node 1 head;

A Linked List Class public class Linked. List 1 { private Node 1 head; public Linked. List 1( ) { head = null; } /** Adds a node at the start of the list with the specified data. The added node will be the first node in the list. */ public void add. To. Start(String item. Name, int item. Count) { head = new Node 1(item. Name, item. Count, head); } CS 102 Algorithms and Programming II 8

A Linked List Class – delete. Head. Node /** Removes the head node and

A Linked List Class – delete. Head. Node /** Removes the head node and returns true if the list contains at least one node. Returns false if the list is empty. */ public boolean delete. Head. Node( ) { if (head != null) { head = head. get. Link( ); return true; } else return false; } CS 102 Algorithms and Programming II 9

A Linked List Class – size /** Returns the number of nodes in the

A Linked List Class – size /** Returns the number of nodes in the list. */ public int size( ) { int count = 0; Node 1 position = head; while (position != null) { count++; position = position. get. Link( ); } return count; } CS 102 Algorithms and Programming II 10

A Linked List Class – find public boolean contains(String item) { return (find(item) !=

A Linked List Class – find public boolean contains(String item) { return (find(item) != null); } /** Finds the first node containing the target item, and returns a reference to that node. If target is not in the list, null is returned. */ private Node 1 find(String target) { Node 1 position = head; String item. At. Position; while (position != null) { item. At. Position = position. get. Item( ); if (item. At. Position. equals(target)) return position; position = position. get. Link( ); } return null; //target was not found } CS 102 Algorithms and Programming II 11

A Linked List Class – output. List public void output. List( ) { Node

A Linked List Class – output. List public void output. List( ) { Node 1 position = head; while (position != null) { System. out. println(position. get. Item( ) + " " + position. get. Count( )); position = position. get. Link( ); } } public boolean is. Empty( ) { return (head == null); } public void clear( ) { head = null; } } CS 102 Algorithms and Programming II 12

Traversing a Linked List • If a linked list already contains nodes, it can

Traversing a Linked List • If a linked list already contains nodes, it can be traversed as follows: – Set a local variable equal to the value stored by the head node (its reference) – This will provides the location of the first node – After accessing the first node, the accessor method for the link instance variable will provide the location of the next node – Repeat this until the location of the next node is equal to null CS 102 Algorithms and Programming II 13

Traversing a Linked List CS 102 Algorithms and Programming II 14

Traversing a Linked List CS 102 Algorithms and Programming II 14

Adding a Node to a Linked List • The method adds a node to

Adding a Node to a Linked List • The method adds a node to the start of the linked list – This makes the new node become the first node on the list • The variable head gives the location of the current first node of the list – Therefore, when the new node is created, its link field is set equal to head – Then head is set equal to the new node CS 102 Algorithms and Programming II 15

Adding a Node to a Linked List CS 102 Algorithms and Programming II 16

Adding a Node to a Linked List CS 102 Algorithms and Programming II 16

Deleting the Head Node from a Linked List • The method delete. Head. Node

Deleting the Head Node from a Linked List • The method delete. Head. Node removes the first node from the linked list – It leaves the head variable pointing to (i. e. , containing a reference to) the old second node in the linked list • The deleted node will automatically be collected and its memory recycled, along with any other nodes that are no longer accessible – In Java, this process is called automatic garbage collection CS 102 Algorithms and Programming II 17

A Linked List Demonstration public class Linked. List 1 Demo { public static void

A Linked List Demonstration public class Linked. List 1 Demo { public static void main(String[] args) { Linked. List 1 list = new Linked. List 1( ); list. add. To. Start("Apples", 1); list. add. To. Start("Bananas", 2); list. add. To. Start("Cantaloupe", 3); System. out. println("List has " + list. size( ) + " nodes. "); list. output. List( ); if (list. contains("Cantaloupe")) System. out. println("Cantaloupe is on list. "); else System. out. println("Cantaloupe is NOT on list. "); CS 102 Algorithms and Programming II 18

A Linked List Demonstration (cont. ) list. delete. Head. Node( ); if (list. contains("Cantaloupe"))

A Linked List Demonstration (cont. ) list. delete. Head. Node( ); if (list. contains("Cantaloupe")) System. out. println("Cantaloupe is on list. "); else System. out. println("Cantaloupe is NOT on list. "); while (list. delete. Head. Node( )) ; //Empty loop body System. out. println("Start of list: "); list. output. List( ); System. out. println("End of list. "); } } CS 102 Algorithms and Programming II 19

Node Inner Classes • Note that the linked list class discussed so far is

Node Inner Classes • Note that the linked list class discussed so far is dependent on an external node class • A linked list or similar data structure can be made self-contained by making the node class an inner class • A node inner class so defined should be made private, unless used elsewhere – This can simplify the definition of the node class by eliminating the need for accessor and mutator methods – Since the instance variables are private, they can be accessed directly from methods of the outer class without causing a privacy leak • The original node and linked list classes examined so far have a dangerous flaw – The node class accessor method returns a reference to a node – Recall that if a method returns a reference to an instance variable of a mutable class type, then the private restriction on the instance variables can be easily defeated – The easiest way to fix this problem would be to make the node class a private inner class in the linked list class CS 102 Algorithms and Programming II 20

Node Inner Classes public class Linked. List 2 { private class Node { private

Node Inner Classes public class Linked. List 2 { private class Node { private String item; private Node link; It doesn’t make any difference whether we make instance variables item and link private or public. They can still accesible by outer class. public Node( ) { item = null; link = null; } public Node(String new. Item, Node link. Value) { item = new. Item; link = link. Value; } }//End of Node inner class CS 102 Algorithms and Programming II 21

Node Inner Classes -- Linked. List 2 private Node head; public Linked. List 2(

Node Inner Classes -- Linked. List 2 private Node head; public Linked. List 2( ) { head = null; } /** Adds a node at the start of the list with the specified data. The added node will be the first node in the list. */ public void add. To. Start(String item. Name) { head = new Node(item. Name, head); } CS 102 Algorithms and Programming II 22

Node Inner Classes -- delete. Head. Node /** Removes the head node and returns

Node Inner Classes -- delete. Head. Node /** Removes the head node and returns true if the list contains at least one node. Returns false if the list is empty. */ public boolean delete. Head. Node( ) { if (head != null) { head = head. link; return true; } else return false; } CS 102 Algorithms and Programming II 23

Node Inner Classes -- size /** Returns the number of nodes in the list.

Node Inner Classes -- size /** Returns the number of nodes in the list. */ public int size( ) { int count = 0; Node position = head; while (position != null) { count++; position = position. link; } return count; } CS 102 Algorithms and Programming II 24

Node Inner Classes -- find public boolean contains(String item) { return (find(item) != null);

Node Inner Classes -- find public boolean contains(String item) { return (find(item) != null); } /** Finds the first node containing the target item, and returns a reference to that node. If target is not in the list, null is returned. */ private Node find(String target) { Node position = head; String item. At. Position; while (position != null) { item. At. Position = position. item; if (item. At. Position. equals(target)) return position; position = position. link; } return null; //target was not found } CS 102 Algorithms and Programming II 25

Node Inner Classes -- output. List public void output. List( ) { Node position

Node Inner Classes -- output. List public void output. List( ) { Node position = head; while (position != null) { System. out. println(position. item ); position = position. link; } } public boolean is. Empty( ) { return (head == null); } public void clear( ) { head = null; } CS 102 Algorithms and Programming II 26

Node Inner Classes -- equals /* For two lists to be equal they must

Node Inner Classes -- equals /* For two lists to be equal they must contain the same data items in the same order. */ public boolean equals(Object other. Object) { if (other. Object == null) return false; else if (get. Class( ) != other. Object. get. Class( )) return false; else { Linked. List 2 other. List = (Linked. List 2)other. Object; if (size( ) != other. List. size( )) return false; Node position = head; Node other. Position = other. List. head; while (position != null) { if ( (!(position. item. equals(other. Position. item)))) return false; position = position. link; other. Position = other. Position. link; } return true; //A mismatch was not found } } CS 102 Algorithms and Programming II 27

A Generic Linked List • A linked list can be created whose Node class

A Generic Linked List • A linked list can be created whose Node class has a type parameter T for the type of data stored in the node – Therefore, it can hold objects of any class type, including types that contain multiple instance variable – The type of the actual object is plugged in for the type parameter T • For the most part, this class can have the same methods, coded in basically the same way, as the previous linked list example – The only difference is that a type parameter is used instead of an actual type for the data in the node CS 102 Algorithms and Programming II 28

A Generic Linked List Class public class Linked. List 3<T> { This linked list

A Generic Linked List Class public class Linked. List 3<T> { This linked list holds objects of type private class Node<T> { T class. The type T class must have private T data; well-defined equals and private Node<T> link; to. String methods public Node( ) { data = null; link = null; } public Node(T new. Data, Node<T> link. Value) { data = new. Data; link = link. Value; } }//End of Node<T> inner class private Node<T> head; public Linked. List 3( ) { head = null; } CS 102 Algorithms and Programming II 29

A Generic Linked List Class -- add. To. Start /** Adds a node at

A Generic Linked List Class -- add. To. Start /** Adds a node at the start of the list with the specified data. The added node will be the first node in the list. */ public void add. To. Start(T item. Data) { head = new Node<T>(item. Data, head); } /** Removes the head node and returns true if the list contains at least one node. Returns false if the list is empty. */ public boolean delete. Head. Node( ) { if (head != null) { head = head. link; return true; } else return false; } CS 102 Algorithms and Programming II 30

A Generic Linked List Class -- size /** Returns the number of nodes in

A Generic Linked List Class -- size /** Returns the number of nodes in the list. */ public int size( ) { int count = 0; Node<T> position = head; while (position != null) { count++; position = position. link; } return count; } public boolean contains(T item) { return (find(item) != null); } CS 102 Algorithms and Programming II 31

A Generic Linked List Class -- find /** Finds the first node containing the

A Generic Linked List Class -- find /** Finds the first node containing the target item, and returns a reference to that node. If target is not in the list, null is returned. */ private Node<T> find(T target) { Node<T> position = head; T item. At. Position; while (position != null) { item. At. Position = position. data; if (item. At. Position. equals(target)) return position; position = position. link; } return null; //target was not found } /** Finds the first node containing the target and returns a reference to the data in that node. If target is not in the list, null is returned. */ public T find. Data(T target) { return find(target). data; } CS 102 Algorithms and Programming II 32

A Generic Linked List Class -- output. List public void output. List( ){ Node<T>

A Generic Linked List Class -- output. List public void output. List( ){ Node<T> position = head; while (position != null) { System. out. println(position. data); position = position. link; } } public boolean is. Empty( ) { return (head == null); } public void clear( ) { head = null; } CS 102 Algorithms and Programming II 33

A Generic Linked List Class -- equals /* For two lists to be equal

A Generic Linked List Class -- equals /* For two lists to be equal they must contain the same data items in the same order. The equals method of T is used to compare data items. */ public boolean equals(Object other. Object) { if (other. Object == null) return false; else if (get. Class( ) != other. Object. get. Class( )) return false; else { Linked. List 3<T> other. List = (Linked. List 3<T>)other. Object; if (size( ) != other. List. size( )) return false; Node<T> position = head; Node<T> other. Position = other. List. head; while (position != null) { if (!(position. data. equals(other. Position. data))) return false; position = position. link; other. Position = other. Position. link; } return true; //no mismatch was not found } } CS 102 Algorithms and Programming II 34

A Sample Class for the Data in a Generic Linked List public class Entry

A Sample Class for the Data in a Generic Linked List public class Entry { private String item; private int count; public Entry(String item. Data, int count. Data) { item = item. Data; count = count. Data; } public String to. String( ) { return (item + " " + count); } CS 102 Algorithms and Programming II 35

A Sample Class for the Data in a Generic Linked List public boolean equals(Object

A Sample Class for the Data in a Generic Linked List public boolean equals(Object other. Object) { if (other. Object == null) return false; else if (get. Class( ) != other. Object. get. Class( )) return false; else { Entry other. Entry = (Entry)other. Object; return (item. equals(other. Entry. item) && (count == other. Entry. count)); } } // <There should be other constructors and methods, including accessor and // mutator methods, but we do not use them in this demonstration. > } CS 102 Algorithms and Programming II 36

A Generic Linked List Demonstration public class Generic. Linked. List. Demo { public static

A Generic Linked List Demonstration public class Generic. Linked. List. Demo { public static void main(String[] args) { Linked. List 3<Entry> list = new Linked. List 3<Entry>( ); Entry entry 1 = new Entry("Apples", 1); list. add. To. Start(entry 1); Entry entry 2 = new Entry("Bananas", 2); list. add. To. Start(entry 2); Entry entry 3 = new Entry("Cantaloupe", 3); list. add. To. Start(entry 3); System. out. println("List has " + list. size( ) + " nodes. "); list. output. List( ); System. out. println("End of list. "); } } CS 102 Algorithms and Programming II 37

Iterators • A collection of objects, such as the nodes of a linked list,

Iterators • A collection of objects, such as the nodes of a linked list, must often be traversed in order to perform some action on each object – An iterator is any object that enables a list to be traversed in this way • A linked list class may be created that has an iterator inner class – If iterator variables are to be used outside the linked list class, then the iterator class would be made public – The linked list class would have an iterator method that returns an iterator for its calling object – Given a linked list named list, this can be done as follows: Linked. List 2 Iterator i = list. iterator(); • The basic methods used by an iterator are as follows: – restart: Resets the iterator to the beginning of the list – has. Next: Determines if there is another data item on the list – next: Produces the next data item on the list CS 102 Algorithms and Programming II 38

A Linked List with an Iterator public class Linked. List 2 Iter { private

A Linked List with an Iterator public class Linked. List 2 Iter { private class Node { private String item; private Node link; public Node( ) { item = null; link = null; } public Node(String new. Item, Node link. Value) { item = new. Item; link = link. Value; } }//End of Node inner class CS 102 Algorithms and Programming II 39

A Linked List with an Iterator public class List 2 Iterator { private Node

A Linked List with an Iterator public class List 2 Iterator { private Node position; private Node previous; public List 2 Iterator() { position = head; previous = null; } public void restart() { position = head; previous = null; } CS 102 Algorithms and Programming II 40

A Linked List with an Iterator – next public String next() { if (!has.

A Linked List with an Iterator – next public String next() { if (!has. Next()) return ""; String to. Return = position. item; previous = position; position = position. link; return to. Return; } public boolean has. Next() { return (position != null); } public String peek() { if (!has. Next()) return ""; return position. item; } CS 102 Algorithms and Programming II 41

A Linked List with an Iterator – add. Here public void add. Here(String new.

A Linked List with an Iterator – add. Here public void add. Here(String new. Data){ if (position == null && previous != null) { // at end of list previous. link = new Node(new. Data, null); } else if (position == null || previous == null) // at head of list Linked. List 2 Iter. this. add. To. Start(new. Data); else { // Between nodes Node temp = new Node(new. Data, position); previous. link = temp; previous = temp; } } CS 102 Algorithms and Programming II 42

A Linked List with an Iterator – delete public void delete() { if (position

A Linked List with an Iterator – delete public void delete() { if (position == null) {} else if (previous == null) { head = head. link; position = head; } else { previous. link = position. link; position = position. link; } } } //End of List 2 Iterator inner class CS 102 Algorithms and Programming II 43

A Linked List with an Iterator – add. Here private Node head; public List

A Linked List with an Iterator – add. Here private Node head; public List 2 Iterator iterator() { return new List 2 Iterator(); } public Linked. List 2 Iter( ) { head = null; } /** Adds a node at the start of the list with the specified data. The added node will be the first node in the list. */ public void add. To. Start(String item. Name) { head = new Node(item. Name, head); } CS 102 Algorithms and Programming II 44

A Linked List with an Iterator – Test public static void main(String[] args) {

A Linked List with an Iterator – Test public static void main(String[] args) { Linked. List 2 Iter list = new Linked. List 2 Iter(); Linked. List 2 Iterator i = list. iterator(); list. add. To. Start("shoes"); list. add. To. Start("orange juice"); list. add. To. Start("coat"); System. out. println("List contains"); i. restart(); while (i. has. Next()) System. out. println(i. next()); System. out. println(); i. restart(); i. next(); i. delete(); CS 102 Algorithms and Programming II 45

A Linked List with an Iterator – Test System. out. println("List now contains"); i.

A Linked List with an Iterator – Test System. out. println("List now contains"); i. restart(); while (i. has. Next()) System. out. println(i. next()); System. out. println(); i. restart(); i. next(); i. add. Here("socks"); i. restart(); while (i. has. Next()) System. out. println(i. next()); System. out. println(); } CS 102 Algorithms and Programming II 46

Adding and Deleting Nodes • An iterator is normally used to add or delete

Adding and Deleting Nodes • An iterator is normally used to add or delete a node in a linked list • Given iterator variables position and previous, the following two lines of code will delete the node at location position: previous. link = position. link; position = position. link; – Note: previous points to the node before position CS 102 Algorithms and Programming II 47

Deleting a Node CS 102 Algorithms and Programming II 48

Deleting a Node CS 102 Algorithms and Programming II 48

Deleting a Node CS 102 Algorithms and Programming II 49

Deleting a Node CS 102 Algorithms and Programming II 49

Adding and Deleting Nodes • Note that Java has automatic garbage collection – In

Adding and Deleting Nodes • Note that Java has automatic garbage collection – In many other languages the programmer has to keep track of deleted nodes and explicitly return their memory for recycling – This procedure is called explicit memory management • The iterator variables position and previous can be used to add a node as well – previous will point to the node before the insertion point, and position will point to the node after the insertion point Node temp = new Node(new. Data, position); previous. link = temp; CS 102 Algorithms and Programming II 50

Adding a Node between Two Nodes CS 102 Algorithms and Programming II 51

Adding a Node between Two Nodes CS 102 Algorithms and Programming II 51

Adding a Node between Two Nodes CS 102 Algorithms and Programming II 52

Adding a Node between Two Nodes CS 102 Algorithms and Programming II 52