Title: Stuff
1Stuff
- Reminder Midterm exam in JEF234 on March 9th
from 7-9pm. - Lab 6 for this week is posted.
- Assignment 3 is posted due March 10th.
- Assignment 2 due the end of this week March 3rd.
2Last Time
- Use of assertions and invariants to prove
correctness. - You read about ArrayLists, right?
3Today
- Leading up to Linked Lists
- An overall comparison of three different kinds of
data structures - Arrays
- ArrayLists
- Linked Lists
- Then Singly Linked Lists.
4Comparison of Arrays, ArrayLists and Linked Lists
- Arrays can be useful because
- The convenient notation allows immediate
access to any element in the array. - Arrays can directly hold primitive types, as well
as objects. - Primitive type storage is efficient, since the
use of a Wrapper class is not necessary.
5Comparison of Arrays, ArrayLists and Linked Lists
- Cont.
- Arrays can be a problem because
- The size of the array must be known or at least
estimated before the array can be used. - Increasing the size of an array can be very time
intensive. How would you do this? - Arrays can only use a contiguous block of memory.
When a new element is inserted into an array,
all elements above the new one must be shifted up.
6Comparison of Arrays, ArrayLists and Linked Lists
Cont.
- ArrayLists are useful because
- Sizing is no longer a problem.
- They are built-in to the java.util class.
- They inherit many useful methods.
- ArrayListltgt (The generic ArrayList class.)
elements do not need to be cast back to the
original element type.
7Comparison of Arrays, ArrayLists and Linked Lists
Cont.
- An ArrayList can be a problem because
- Arrays are still used (in the background).
- Every re-sizing of the ArrayList causes a time
lag, since a new array must be created in another
block of memory and all the elements copied over. - Element insertion is just as time-consuming as
with arrays, and possibly even worse if the
ArrayList has to be resized. - It can only store Objects, not primitive types.
- Do not have the handy notation, only methods.
8Linked Lists
- A singly linked list consists of Objects called
nodes that contain data and a link to the next
node in the list - A node is defined in one class, and another
class, the linked list class, contains the head
and tail pointers.
tail
head
15
10
5
20
null
9Comparison of Arrays, ArrayLists and Linked Lists
Cont.
- Linked lists are useful because
- Can store primitive types or Objects or any
combination of the above. - A node can be anywhere in memory. The list does
not have to occupy a contiguous memory space. - List size is only limited by available memory,
and does not have to be declared first. - No empty nodes.
- The adding, insertion or deletion of list
elements or nodes can be accomplished with the
minimal disruption of neighbouring nodes.
10Comparison of Arrays, ArrayLists and Linked Lists
Cont.
- Problems with linked lists include
- A node is not necessarily an efficient storage
Object (in terms of memory usage), since it must
hold links to other nodes in addition to the data
item(s). - In order to access any one node in a linked list,
all links must be followed from the head of the
list to get to that certain node. Nothing like
the notation of arrays.
11Choosing a Data Structure
- To choose, it helps to know such things as
- Can a maximum number of elements be defined or
anticipated? - How often will new elements be added to the
structure after it is created? - Will re-ordering of the elements be necessary,
and how often? - If the structure is ordered, how often will
elements need to be inserted?
12Choosing a Data Structure Cont.
- Will memory usage be critical?
- Is execution speed critical?
- How often will re-sizing be necessary?
- Is the data element a primitive type or an
Object? - How often will it be necessary to access elements
in the middle or end part of the data structure,
or will the top level elements be accessed more
often?
13Choosing a Data Structure Cont.
- There are many other data structures available,
including trees and hash tables. - You can build a structure yourself or use a
canned version already coded into Java. - The final choice will always be a compromise!
- Ultimately, you may have to resort to timing
execution speeds (ie. experiment!) to find the
best data structure. - On the next slide, the generic data structures
already in Java
14Interface
Implement
Abstract Class
Extend
CollectionltTgt
Concrete Class
ListltTgt
SetltTgt
AbstractCollectionltTgt
SortedSetltTgt
AbstractSetltTgt
AbstractSetltTgt
AbstractSequentialListltTgt
ArrayListltTgt
VectorltTgt
TreeSetltTgt
HashSetltTgt
LinkedListltTgt
15Linked Lists
- A linked list class, called LinkedList is
available from the java.utils package. It is of
the generic doubly linked list type. - In order to learn how the LinkedList class works,
it is necessary to construct a list from
scratch. (It is also a good illustration of
how objects work!) - Also, it may be necessary to build a different or
more advanced type of list from what is available
in LinkedList. - A singly linked list only contains one link to
the next node
16Singly Linked List - Node Class
- public class IntNode
- public int info // a data value
- public IntNode next // a link
- // constructors
- public IntNode (int i) this(i, null)
- public IntNode (int i, IntNode n)
- info i
- next n
-
- // end IntNode
17Aside The this Keyword
- It is used by one constructor to invoke another
in the same class. - It is a way for an object to obtain a reference
to itself. - You dont have to use this this thing! See the
next slide for another version of the node class
18Singly Linked List - Node Class, ver.2
- public class IntNode
- public int info // a data value
- public IntNode next // a link
- // constructors
- public IntNode (int i)
- info i
- next null
-
- public IntNode (int i, IntNode n)
- info i
- next n
-
- // end IntNode
19Singly Linked List Cont.
- The data value could just as easily be an
Object - public class IntNode
- public StudentInfo info //a data Object
- public IntNode next // a link
- // constructors
- public IntNode (StudentInfo s) this(s, null)
- public IntNode (StudentInfo s, IntNode n)
- info s
- next n
-
- // end IntNode
20Singly Linked List Cont.
- For simplicity, we will continue to consider a
link holding an int value, info. - For example, create a linked list of three
integers, 10, 8 and 50
21Singly Linked List Cont.
- First statement
- IntNode p new IntNode(10)
- As usual, this operation takes place in four
stages
(ii)
(i)
p
p
10
info
next
p
p
10
10
null
null
(iv)
(iii)
22Singly Linked List Cont.
- The above initialization uses the first
constructor, which sets the value of info to 10
and sets the value of next to null. - The next node is created using
- p.next new IntNode(8)
23Singly Linked List Cont.
p
10
null
p
10
8
null
p
10
8
null
null
p
10
8
null
24Singly Linked List Cont.
- The last node (50) is added using
- p.next.next new IntNode(50)
p
10
8
50
null
25Singly Linked List Cont.
- Note that the last node always contains null.
- Right now, the list is only accessible through
the variable p, so the cumbersome chain of
nexts must be used to get at the individual
elements. - (What happens to the list if you coded p
null?) - Imagine having to use 1000 nexts for a larger
linked list of 1000 integers! - Introduce another class that will keep track of
the head and tail positions of the list
26- public class IntSLList // A singly linked
- // list with a head and tail
- private IntNode head
- private IntNode tail
- public IntSLList ()
- head null
- tail null
-
- public void addToHead (int aNum)
- head new IntNode(aNum, head)
- if (tail null) tail head
-
- // more methods to be developed!
- // end IntSLList
27Singly Linked List - Node Class (again)
- public class IntNode
- public int info // a data value
- public IntNode next // a link
- // constructors
- public IntNode (int i) this(i, null)
- public IntNode (int i, IntNode n)
- info i
- next n
-
- // end IntNode
28Singly Linked List Cont.
- Create a list using
- IntSLList list new IntSLList()
list
null
head
null
tail
29Singly Linked List Cont.
- list.addToHead(5) // step i
- list.addToHead(10) // step ii
- list.addToHead(15) // step iii
list
IntNodes
head
5
null
tail
head
10
5
null
tail
15
10
5
head
null
tail
30Singly Linked List Cont.
- Now either end of the linked list can be located
using the head or tail pointers, without using a
cumbersome chain of nexts.
31Singly Linked List Cont.
- Simplify notation. This
- Is the same as
15
head
10
5
null
tail
tail
head
15
10
5
null
32Singly Linked List Cont.
- Mechanism of adding another node
- list.addToHead(20)
- addToHead method
- public void addToHead (int aNum)
- head new IntNode(aNum, head)
- if (tail null) tail head
-
33Singly Linked List Cont.
tail
head
15
10
5
null
head
tail
15
10
5
20
null
head
tail
15
10
5
20
null
head
tail
15
10
5
20
null
34Singly Linked List Cont.
- A method to add a new node to the tail of the
list - public boolean isEmpty()
- return head null
-
- public void addToTail (int aNum)
- if (!isEmpty())
- tail.next new IntNode(aNum)
- tail tail.next
- else
- head new IntNode(aNum)
- tail head
-
- // end addToTail
35Singly Linked List Cont.
head
tail
15
10
5
20
null
head
tail
15
10
5
20
-5
null
head
tail
15
10
5
20
-5
null
null
head
tail
15
10
5
20
-5
null
head
tail
15
10
5
20
-5
null
36Singly Linked List Cont.
- Why not use tail new IntNode(aNum)?
- Can a node be inserted in the middle of the
list, as easily as at the head or tail? Why
would you want to?
- Does it make sense to sort a linked list?
- How would you add a node at the end of the
linked list without a tail pointer?
37Singly Linked List Use of Inner Classes
- The node object, IntNode, is a public class and
its attributes (info and next) are public. - This is necessary so that the IntSLList class can
use the node class. - This is not good containment or information
hiding practice. - But if the class IntNode and its attributes are
declared private, how can they be used by the
linked list class?
38Use of Inner Classes - Cont.
- Remember how private attributes are available
(their scope) anywhere inside a class, but not
outside the class? - In fact, within the class, it does not matter if
an attribute is private or public. - Java will allow the definition of a class within
a class - Inner Classes - and now the
attributes in the inner class can be declared
private. - Re-define IntSLList as
39Use of Inner Classes Cont.
- public class IntSLList
-
- private IntNode head
- private IntNode tail
- private class IntNode
- private int info
- private IntNode next
- public IntNode (int i) this(i, null)
- public IntNode (int i, IntNode n)
- info i next n
-
- // end IntNode
- // rest of IntSLList methods, constructors
- // end IntSLList
40Use of Inner Classes Cont.
- Note that even though the inner class is private
it can be used by IntSLList because it has been
defined inside of this class. - Or, the scope of IntNode is anywhere inside the
IntSLList class. - IntNode and its attributes are not available
outside IntSLList.
Much Better!
41Writing Linked List Methods
- Note that each method must work for
- An empty list,
- A list with just one node, and
- A list with two or more nodes.
- We have methods to
- Create a list (the constructor)
- Add to the head of the list
- Check for an empty list
- Add to the tail of the list
- What other methods would be useful?
42Singly Linked List - Other Methods
- Deleting a head node.
- Deleting all nodes!
- Deleting an inner node (not head or tail).
- Deleting a tail node.
- Others
- Searching for a certain node.
- Counting nodes.
- Adding a inner node (but why?)
43Singly Linked List - Deleting Nodes
- Note that a deleting method may or may not return
the data value or a link to the data Object that
it has deleted. We will assume that the deleting
method returns the value. - The calling method can choose not to do anything
with this value. - Note that these deleting methods will return a
value of -1 if the list is empty. What else
could we do here?
44Deleting the Head Node
- public int removeFromHead ()
- if (isEmpty()) return -1
- int i head.info
- if (head.next null)
- head null
- tail null
-
- else
- head head.next
- return i
- // end removeFromHead
45Deleting the Head Node, Cont.
tail
head
15
10
5
null
tail
head
Poof!
15
10
5
null
- What happens to the node with 15?
46Deleting All Nodes
- public void clearList()
- if (!isEmpty())
- head null
- tail null
- // end if
- // end clearList
- Nodes that are no longer pointed to are garbage
collected!
47Deleting the Node that Contains the Value delNum
- First, locate the node, then delete it.
- It is way too big a method to show on this
slide!! - See the next one
48- public void delete (int delNum) // does not
return i - if (!isEmpty())
- if (headtail delNumhead.info)
- head null tail null // only 1 node
- else if (delNum head.info)
- // delete first node, more nodes in list
- head head.next
- else
- IntNode pred head
- IntNode temp head.next
- while (temp ! null temp.info ! delNum)
- pred pred.next
- temp temp.next
- // end while
- if (temp ! null)
- pred.next temp.next
- if (tail temp) tail pred
- // end if
- // end else
49Deleting a Certain Node, Cont.
- How would we modify this method to return a
value? - Would you return -1? Under what conditions?
50Deleting an Inner Node - An Example
pred
temp
head
tail
15
10
5
20
-5
null
pred
temp
head
tail
15
10
5
20
-5
null
pred
temp
head
tail
15
10
5
20
-5
null
pred.next temp.next
51Deleting an Inner Node Cont.
- What happens to the node that is pointed to by
temp, when the delete method completes?
Poof! Gone!
(The node is garbage collected when execution
moves beyond the scope of the variable temp.)
52Deleting an Inner Node Iterators
- Note the use of the pred and temp objects in the
delete method - (Java jargon) These are called iterators
because they are used to move through the list.
53Deleting a Tail Node
- So how is this going to work?
- How can the tail pointer be moved up to the
preceding node?
tail
head
15
10
5
20
null
54Deleting a Tail Node - Cont.
- Since there is no link from the tail node to the
previous node, the only way is to iterate through
the entire list, starting from the head, until
the tail is reached. - (How can you tell when you have reached the
tail?) - Two iterators must be used (Why?), as in the
delete method
55- public int removeTail ()
- int i -1
- if (!isEmpty())
- i tail.info
- if (head tail)
- head null tail null
- else
- IntNode pred head
- IntNode temp head.next
- while (temp.next ! null)
- pred pred.next
- temp temp.next
- // end while
- tail pred
- tail.next null
- // end else
- // end if
- return i
- // end removeTail method
56Deleting a Tail Node - Cont.
- That was a lot of work!
- Deleting the tail node this way is more time
consuming than deleting an inner node. - Would it not be nice if the tail node already had
a link pointing to the previous node? - No problem! Create a doubly linked list.