Lecture 9:
Doubly Linked & Circular Lists
Announcements
H2: possible misgrading,
and subtle issue
want to make
sure everyone understands
isDuplicate should throw an exception
if pos is not a legal
position
one solution:
explicit test (as in the posted solution)
other possible
valid solutions:
1. Object ob = get(pos);
can omit the explicit test
for bad position
2. Object ob = items[pos];
can omit the test for pos<0
check your homework
grades, make sure you understand the
points you missed, come ask if you think
you deserved more points
H3
is due today
H4 is
last homework before exam; due on-line by
Exam: Thurs, Feb 24,
can bring: one page of notes
two previous
exams on-line -- format will be similar
P1 are graded;
OUTPUT
NEEDS TO MATCH SPECIFICATION
No points deducted this time, but will
deduct in future
Feedback
given on style problems
No points deducted for style, but will deduct on
P2
If you have any questions about style,
come by to discuss
Doubly linked list
Recall: given only
ptr to first node in the list, and
tmp ptr
to node n in the list
operations that
are O(1):
add
node after node n
add node
after node 1
operations that are O(N):
remove
node n
to make this "remove node n" operation O(1):
use a doubly
linked list
·
each
node has two pointers, one to "next" and one to "prev"
·
each
pointer points to the whole object
·
pointers
are null at ends of list
class DblListnode {
private Object
data;
private DblListnode next;
private DblListnode prev;
// 1, 2, and 3 arg
constructors
}
How to remove node pointed to by
tmp:
Before:
After:
tmp
When tmp is not pointing
to the first or last node:
In English, what needs to
be done? (call
on someone)
set next field of
tmp.getPrev() equal to tmp.getNext()
set prev field of tmp.getNext() equal
to tmp.getPrev()
Take a couple of minutes to write the code:
(if you
finish compare to the person next to you)
solution:
tmp.getPrev().setNext(tmp.getNext());
tmp.getNext().setPrev(tmp.getPrev());
possible special cases:
tmp
points to the first node but not last node
-- if
header, this is not special
tmp
points to the last node
tmp
points to the only node
if
header, this is the same as the last node
you try:
remove node tmp assuming a header node (cover all cases)
if you finish, think about the time complexity
solution:
tmp.getPrev.setNext(tmp.getNext());
if (tmp.getNext()
!= null)
tmp.getNext().setPrev(tmp.getPrev());
Time is? O(1)
== tests for pointer
equality;
ob.equals() tests for equality of
the object fields
Circular lists:
·
Picture of singly linked & doubly linked
·
Useful
representation when common operations are:
remove from beginning and add to end
·
Operations
in notes
Summary of
linked list variations
· doubly vs
singly linked list
o
doubly
linked makes some operations more efficient
e.g.,
remove node n, traverse right to left
o
doubly
linked takes more space
o
doubly
linked code must maintain prev fields
· circular lists
o
can
eliminate some special cases
o
traversals
more complicated
(need to prevent infinite loop)
Testing
·
very
important part of programming
·
not much fun(?)
but very satisfying to have code that is bug-free!
Goal: bug-free software
2
general approaches:
·
black
box testing
·
white
box texting
use both to test your code
black box testing
·
tester
only has external view (knows interface
but not implementation)
·
testing
includes
·
test
every operation (i.e., every public method)
·
test
wide range of inputs, especially boundary cases
·
test
normal and unexpected inputs
·
example: List class
(unexpected inputs are underlined)
try each method on list with
no/one/many items
try sequences that might find
errors & error inputs
e.g., contains(null)
contains(a) after add(a)
contains(get(size()-1))
contains(get(0))
contains(get(k)) where 0 < k < size()-1
add(null)
add(ob)
add()
add(size(),
ob),
add(0, null)
add(0,ob)
add(k,ob) where 0 < k < size()-1
get(0)
get(size()-1)
get(size())
get(k) where 0 < k < size()-1
remove(size()),
remove(size()-1) followed by add(ob)
etc.
String s =
a;
create new List
L, k
= L.size()
L.get(0), L.remove(0), L.add(1,a)
L.add(0,a), L.size(), ob = L.get(0)
L.get(1), L.remove(1), L.add(2,a)
L.remove(0), L.contains(null), L.contains(),
L.get(0), L.size(), L.remove(0)
L.add(a), if(!ob.equals(L.get(0))) error msg
L.add(aa,0); if(!ob.equals(L.get(1))) error msg
L.contains(null) , L.contains((a),
L.contains(L.get(0))
for(int k=0,
k<1000,k++) { L.add(s);}
L.size(), if(!ob.equals(L.remove(1001))) error msg
L.size(), L.add(a),
if(!ob.equals(L.remove(1001))) error msg
for(int k=0,
k<10,k++)
{L.add(0,s); s = s + "a"};
if (!ob.equals(L.remove(11))) error msg
You try
Think
of some more cases to test the LinkedList class
white box testing
·
tester
does know the implementation
·
goal: coverage,
- every
private method is tested
- every
line of code executes in at least one test
(not practical in large production software)
Example: List class
Test enough called to add(ob) to cause
array to be expanded
For
P2, 10% of grade is your test program
Come and ask if you have any questions