Linked Lists: Computer Science E-119 Harvard Extension School Fall 2012 David G. Sullivan, PH.D
Linked Lists: Computer Science E-119 Harvard Extension School Fall 2012 David G. Sullivan, PH.D
• The last node in the linked list has a link value of null.
• Here’s how the above linked list might actually look in memory:
0x200 0x520 the variable items
0x204
0x208 72
the last node
0x212 null
0x216
… …
0x520 31
the first node
0x524 0x812
0x528
… …
0x812 52
the second node
0x816 0x208
after:
31 52 72
items
null
63
• Disadvantages:
• they don’t provide random access
• need to “walk down” the list to access an item
• the links take up additional memory
A String as a Linked List of Characters
‘c’ ‘a’ ‘t’
str1
null
Tracing length()
public static int length(StringNode str) {
if (str == null)
return 0;
else
return 1 + length(str.next);
}
0x128 0x720 0x404
ch ‘c’ ‘a’ ‘t’
str1
next null
• Example: StringNode.length(str1)
str:null
return 0;
str:0x404 str:0x404 str:0x404
“t” “t” return 1+0
str:0x720 str:0x720 str:0x720 str:0x720 str:0x720
“at” “at” “at” “at”
return 1+1
str:0x128 str:0x128 str:0x128 str:0x128 str:0x128 str:0x128 str:0x128
“cat” “cat” “cat” “cat” “cat” “cat”
return 1+2
time
Getting the Node at Position i in a Linked List
• getNode(str, i) – a private helper method that returns a
reference to the ith node in the linked list (i == 0 for the first node)
• Recursive approach:
node at position 2 in the linked list representing “linked”
= node at position 1 in the linked list representing “inked”
= node at position 0 in the linked list representing “nked”
(return a reference to the node containing ‘n’)
ch ‘c’
Review of Variables
next
• A variable or variable expression represents both:
• a “box” or location in memory (the address of the variable)
• the contents of that “box” (the value of the variable)
0x200 0x520 0x812 0x208
• Practice:
str ‘d’ ‘o’ ‘g’
0x204 null
temp
• Example: temp.next.ch
• Start with the start of the expression: temp.next
It represents the next field of the node to which temp refers.
• address =
• value =
• Next, consider temp.next.ch
It represents the ch field of the node to which temp.next refers.
• address =
• value =
Dereferencing a Reference
• Each dot causes us to dereference the reference represented
by the expression preceding the dot.
• Consider again temp.next.ch
• Dereference: temp.next.ch
0x200 0x520 0x812 0x208
str ‘d’ ‘o’ ‘g’
0x204 null
temp
Dereferencing a Reference (cont.)
• Get the next field: temp.next.ch
0x200 0x520 0x812 0x208
str ‘d’ ‘o’ ‘g’
0x204 null
temp
• Dereference: temp.next.ch
0x200 0x520 0x812 0x208
str ‘d’ ‘o’ ‘g’
0x204 null
temp
2) temp = temp.next;
• Recursive approach:
• base case: if str is empty, return null
• else: copy the first character
make a recursive call to copy the rest
return copyFirst;
}
copyFirst ‘g’
str null
copyFirst ‘o’
str null
copyFirst ‘d’
str null
copyFirst ‘g’
str null
copyFirst ‘o’
str null
copyFirst ‘d’
str null
• This return value is stored in the next field of the ‘o’ node:
copyFirst ‘g’
str null
copyFirst ‘o’
str
copyFirst ‘d’
str null
• This return value is stored in the next field of the ‘d’ node:
‘g’
null
copyFirst ‘o’
str
copyFirst ‘d’
str
‘g’
null
‘o’
copyFirst ‘d’
str
‘g’
null
‘o’
‘d’
• It can also be done using iteration (for loops, while loops, etc.).
trav
• Java method:
public static void toUpperCase(StringNode str) {
StringNode trav = str;
while (trav != null) {
trav.ch = Character.toUpperCase(trav.ch);
trav = trav.next;
}
}
(makes use of the toUpperCase() method from Java’s built-in
Character class)
trav
str
and now trav == null, so we break out of the loop and return:
prevNode
newNode ‘f’
newNode ‘f’
prevNode
prevNode
Returning a Reference to the First Node
• Both deleteChar() and insertChar() return a reference to
the first node in the linked list. For example:
private static StringNode deleteChar(StringNode str, int i) {
…
if (i == 0) // case 1
str = str.next;
else { // case 2
StringNode prevNode = getNode(str, i-1);
if (prevNode != null && prevNode.next != null)
prevNode.next = prevNode.next.next;
…
}
return str;
}
• If the first node changes, str will point to the new first node.
trav
• When we exit the loop, where will trav point? Can we insert ‘n’?
• The following changed version doesn’t work either. Why not?
StringNode trav = str;
while (trav != null && trav.next.ch < ch)
trav = trav.next;
Using a “Trailing Reference” (cont.)
• To get around the problem seen on the previous page,
we traverse the list using two different references:
• trav, which we use as before
• trail, which stays one node behind trav
trail trav