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 noon 2/22

 

Exam:  Thurs, Feb 24,  7:15 – 9:15pm,  room 1240 CS

        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