Contents [0/7] |
Video [1/7] |
Example [2/7] |
Insertion logic [3/7] |
The Middle [4/7] |
The End [5/7] |
The Beginning [6/7] |
Cleanup [7/7] |
(Click here for one slide per page)
Video [1/7] |
00:00 Insertion logic 05:53 Finding the correct position 11:06 Dealing with null at the end of the list 15:26 Dealing with null at the beginning of the list 16:20 Whack-A-Mole debugging doesn't work 18:29 Dealing with values at the beginning of the list 21:04 Cleaning up 22:05 Understanding assignment 23:07 Understanding fields that hold references 25:27 Review
Example [2/7] |
Suppose I have a sorted linked list of doubles.
Let's write an insert method.
file:PlaygroundInsert.java [source] [doc-public] [doc-private]
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package algs13; import java.text.DecimalFormat; import stdlib.*; public class PlaygroundInsert { private Node first; static class Node { public double item; public Node next; public Node (double item, Node next) { this.item = item; this.next = next; } } public void insert (double item) { // TODO } public static void main (String[] args) { //Trace.showObjectIdsRedundantly(true); Trace.showBuiltInObjects(true); Trace.drawStepsOfMethod ("insert"); Trace.drawStepsOfMethod ("insertH"); Trace.run (); testInsert ("[ 11 21 31 41 51 ]", "11 21 41 51", 31); //PlaygroundInsert list = of ("11 21 41 51"); //list.insert(31); Trace.draw (); StdOut.println ("Finished tests"); } public static void main1 (String[] args) { testInsert ("[ 11 21 31 41 51 ]", "11 21 41 51", 31); testInsert ("[ 11 21 31 41 51 ]", "11 31 41 51", 21); testInsert ("[ 11 21 31 41 51 ]", "11 21 31 51", 41); testInsert ("[ 11 21 31 41 51 ]", "11 21 31 41", 51); testInsert ("[ 11 ]", "", 11); testInsert ("[ 11 21 31 41 51 ]", "21 31 41 51", 11); StdOut.println ("Finished tests"); } /* ToString method to print */ public String toString () { // Use DecimalFormat #.### rather than String.format 0.3f to leave off trailing zeroes DecimalFormat format = new DecimalFormat ("#.###"); StringBuilder result = new StringBuilder ("[ "); for (Node x = first; x != null; x = x.next) { result.append (format.format (x.item)); result.append (" "); } result.append ("]"); return result.toString (); } /* Method to create lists */ public static PlaygroundInsert of(String s) { PlaygroundInsert result = new PlaygroundInsert (); if ("".equals (s)) return result; Node first = null; String[] nums = s.split (" "); for (int i = nums.length-1; i >= 0; i--) { try { double num = Double.parseDouble (nums[i]); first = new Node (num, first); } catch (NumberFormatException e) { throw new IllegalArgumentException (String.format ("Bad argument \"%s\": could not parse \"%s\" as a double", s, nums[i])); } } result.first = first; return result; } private static void testInsert (String expected, String list, double item) { PlaygroundInsert aList = PlaygroundInsert.of (list); aList.insert (item); String actual = aList.toString (); if (! expected.equals (actual)) { StdOut.format ("Failed [%s].insert(%f): Expecting (%s) Actual (%s)\n", list, item, expected, actual); } } }
Insertion logic [3/7] |
To create this, you work in pieces: first get the insert logic.
11 |
public void insert (double item) { Node x = first.next; Node y = new Node (item, null); Node f = x.next; x.next = y; y.next = f; } |
Passes some tests (inserts the item after first, as long as list is not empty)
Now figure out the loop.
As with all loops we work in pieces:
The Middle [4/7] |
Let suppose the item is going into the middle. Let's figure out how to get to the right place. Use the test inserting 31 into [ 11 21 41 51 ].
11 |
public void insert (double item) { Node x = first; while (x.next.item < item) { x = x.next; } Node y = new Node (item, null); Node f = x.next; x.next = y; y.next = f; } |
Passes more tests
The End [5/7] |
Now figure out what to do if you hit null.
11 |
public void insert (double item) { Node x = first; while (x.next != null && x.next.item < item) { x = x.next; } Node y = new Node (item, null); Node f = x.next; x.next = y; y.next = f; } |
Passes more tests
The Beginning [6/7] |
Now figure out how to start. For this style of list,
we must have a special case, since we need to modify
first
rather than next
.
11 |
public void insert (double item) { if (first == null || first.item >= item) { Node y = new Node (item, null); Node f = first; first = y; y.next = f; } else { Node x = first; while (x.next != null && x.next.item < item) { x = x.next; } Node y = new Node (item, null); Node f = x.next; x.next = y; y.next = f; } } |
Cleanup [7/7] |
11 |
public void insert (double item) { if (first == null || first.item >= item) { first = new Node (item, first); } else { Node x = first; while (x.next != null && x.next.item < item) { x = x.next; } x.next = new Node (item, x.next); } } |
Revised: 2008/03/17 13:01