Pre-Announcement
Jimmy has questions:
Next week, 3:30 - 6 PM in FSM Cafe, drop in info sessions.
Announcements
The College of Engineering is still trying to get us some office hours for M/T/W.
Josh office hours schedule:
�
One Last Note on Plagiarism
Collaboration Policy
We have enumerated very specific rules whose violation will result in an F (see about.html):
Permissible But with Extreme Caution
Were it enforceable, I’d say no looking at code at all, but I want you to take these rules seriously (unlike, say, speed limits).
Plagiarism will (Probably) be Detected, and Dealt with Harshly
Plagiarism detection software is very sophisticated.
We will fail you.
Please contact me if 61B is causing massive disruptions to your life.
Quick Note on Autograders / Debugging
Autograder is not intended to be your debugging tool.
Example: The ReadRadius test is failing in the autograder, but works fine when you run the provided TestReadRadius.java file.
CS61B, Spring 2016
Lecture 5: DLLs and Arrays
Summary of Last Time (From IntList to SList)
List of Improvements:
Doubly Linked Lists
(In Brief)
One (Avoidable) Downside of SLists
Inserting at the back of a list is much slower than the front.
private IntNode getBackNode() {
IntNode p = sentinel;
while (p.next != null) {
p = p.next;
}
return p;
}
public void insertBack(int x) {
IntNode back = getBackNode();
back.next = new IntNode(x, null);
size += 1;
}
Improvement #6: (???) Goal: Fast insertBack
How could we modify our list so that insertBack is also fast?
insertFront()
sentinel
getFront()
value
next
??
3
50
9
3
size
size()
insertBack()
Is .back enough? PollEv.com/jhug or Text JHUG to 37607
Suppose we want to support insert, get, and delete operations, will having a back pointer result for fast operations on long lists?
�If not, which operations would be slow?
insertBack()
sentinel
getBack()
value
next
??
3
50
9
3
size
size()
deleteBack()
back
.back Is Not Enough
Suppose we want to support insert, get, and delete operations, will having a back pointer result for fast operations on long lists?
�If not, which operations would be slow?
sentinel
value
next
??
3
9
3
size
insertBack()
getBack()
size()
deleteBack()
back
50
Improvement #6: .back and ??? Goal: Fast insertBack
We added .back. What other changes might we make so that delete is also fast?
sentinel
value
next
??
3
9
3
size
insertBack()
getBack()
size()
deleteBack()
back
50
Improvement #6: .back and .prev
We added .back. What other changes might we make so that delete is also fast?
sentinel
item
next
??
5
2
size
back
prev
insertBack()
getBack()
size()
deleteBack()
17
item
next
prev
item
next
prev
Doubly Linked Lists (Naive)
Reverse pointers allow all operations (insert, get, delete) to be fast.
sentinel
item
next
??
5
2
size
back
prev
insertBack()
getBack()
size()
deleteBack()
17
0
sentinel
??
size
back
insertBack()
getBack()
size()
deleteBack()
Doubly Linked Lists (Naive)
Non-obvious fact: This approach has an annoying special case: back sometimes points at the sentinel, and sometimes points at a ‘real’ node.
0
sentinel
??
size
back
insertBack()
getBack()
size()
deleteBack()
sentinel
item
next
??
5
2
size
back
prev
insertBack()
getBack()
size()
deleteBack()
17
Doubly Linked Lists (Double Sentinel)
One solution: Have two sentinels.
sentF
item
next
??
5
2
size
sentB
prev
17
??
0
sentF
??
size
sentB
null
??
null
insertBack()
getBack()
size()
deleteBack()
insertBack()
getBack()
size()
deleteBack()
This is one reasonable approach for Project 1A.
Doubly Linked Lists (Circular Sentinel)
Even better topology (IMO):
0
sentinel
??
size
sentinel
5
2
size
17
??
next
item
prev
insertBack()
getBack()
size()
deleteBack()
insertBack()
getBack()
size()
deleteBack()
This is my preferred approach for Project 1A.
Examples:
0
sentinel
??
size
insertBack()
getBack()
size()
deleteBack()
Improvement #7: Fancier Sentinel Node(s)
While fast, adding .back and .prev introduces lots of special cases.
To avoid these, either:
Summary
List of Improvements:
Still many steps before we have an industrial strength data structure. Will discuss over coming weeks.�
Generic SLists
SLists
One issue with our SList class is that it only supports integers.
public class SList {� private IntNode sentinel;
private int size;�
public class IntNode {� public int item;� public IntNode next;�� public IntNode(int i, IntNode n) {� item = i; next = n;� }� }
...�}
SList s1 = new SList(5);
s1.insertFront(10);
SList s2 = new SList("hi");
s2.insertFront("apple");
SListLauncher.java:6: error: incompatible types: String cannot be converted to int
SList s2 = new SList("ape");
SLists
Java allows us to defer type selection until declaration.
public class SList<BleepBlorp> {� private Node sentinel;
private int size;�
public class Node {� public BleepBlorp item;� public Node next;�� public Node(BleepBlorp i, Node n) {� item = i; next = n;� }� }
...�}
SList<Integer> s1 = new SList<Integer>(5);
s1.insertFront(10);
SList<String> s2 = new SList<String>("hi");
s2.insertFront("apple");
Generics
We’ll spend a lot more time with generics later, but here are the rules of thumb you’ll need for project 1:
SList<Double> s1 = new SList<Double>(5.3);
double x = 9.3 + 15.2;
s1.insertFront(x);
reference type
Arrays
Variables and Objects
Variables
Objects are either:
Arrays
Arrays consist of:
Like all objects, arrays are anonymous.
Can access box i with bracket notation, e.g. A[i]
Arrays
Like classes, arrays are (almost always) instantiated with new.
Three valid notations:
�
All three notations create an array, which we saw on the last slide comprises:
Can omit the new if you are also declaring a variable.
Creates array containing 3 int boxes (32 x 3 = 96 bits total). Each container gets a default value.
As an aside: In Oracle’s implementation of Java, all Java objects also have some overhead. Total size of an array=192 + KN bits, where K is the number of bits per item (Sedgewick/Wayne pg. 201 for more)
Array Basics: http://goo.gl/tFyMEJ
int[] z = null;
int[] x, y;
x = new int[]{1, 2, 3, 4, 5};
y = x;
x = new int[]{-1, 2, 5, 4, 99};
y = new int[3];
z = new int[0];
int xL = x.length;
String[] s = new String[6];
s[4] = "ketchup";
s[x[3] - x[1]] = "muffins";
int[] b = {9, 10, 11};
System.arraycopy(b, 0, x, 3, 2);
Array Basics: http://goo.gl/nFYwzU
int[] z = null;
int[] x, y;
x = new int[]{1, 2, 3, 4, 5};
y = x;
x = new int[]{-1, 2, 5, 4, 99};
y = new int[3];
z = new int[0];
int xL = x.length;
String[] s = new String[6];
s[4] = "ketchup";
s[x[3] - x[1]] = "muffins";
int[] b = {9, 10, 11};
System.arraycopy(b, 0, x, 3, 2);
Arraycopy
Two ways to copy arrays:
arraycopy is (likely to be) faster, particularly for large arrays. More compact code.
System.arraycopy(b, 0, x, 3, 2);
(In Python): x[3:5] = b[0:2]
2D Arrays
Arrays of Array Addresses (http://goo.gl/VS4cOK)
int[][] pascalsTriangle;
pascalsTriangle = new int[4][];
int[] rowZero = pascalsTriangle[0];
pascalsTriangle[0] = new int[]{1};
pascalsTriangle[1] = new int[]{1, 1};
pascalsTriangle[2] = new int[]{1, 2, 1};
pascalsTriangle[3] = new int[]{1, 3, 3, 1};
int[] rowTwo = pascalsTriangle[2];
rowTwo[1] = -5;
int[][] matrix;
matrix = new int[4][];
matrix = new int[4][4];
int[][] pascalAgain = new int[][]{{1}, {1, 1},
{1, 2, 1}, {1, 3, 3, 1}};
Array Boxes Can Contain References to Arrays!
int[][] pascalsTriangle;
pascalsTriangle = new int[4][];
int[] rowZero = pascalsTriangle[0];
pascalsTriangle[0] = new int[]{1};
pascalsTriangle[1] = new int[]{1, 1};
pascalsTriangle[2] = new int[]{1, 2, 1};
pascalsTriangle[3] = new int[]{1, 3, 3, 1};
int[] rowTwo = pascalsTriangle[2];
rowTwo[1] = -5;
int[][] matrix;
matrix = new int[4][];
matrix = new int[4][4];
int[][] pascalAgain = new int[][]{{1}, {1, 1},
{1, 2, 1}, {1, 3, 3, 1}};
Array of int array references.
Create four boxes, each can store an int array reference
Create a new array with three boxes, storing integers 1, 2, 1, respectively. Store a reference to this array in pascalsTriangle box #2.
Creates 5 total arrays.
Creates 1 total array.
PollEv.com/jhug or Text JHUG to 37607 (http://goo.gl/fCZ9Dr)
What will be the value of x[0][0] and w[0][0] when the code shown completes?
arraycopy parameters are:
int[][] x = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int[][] z = new int[3][];
z[0] = x[0];
z[1] = x[1];
z[2] = x[2];
z[0][0] = -z[0][0];
int[][] w = new int[3][3];
System.arraycopy(x[0], 0, w[0], 0, 3);
System.arraycopy(x[1], 0, w[1], 0, 3);
System.arraycopy(x[2], 0, w[2], 0, 3);
w[0][0] = -w[0][0];
Arrays vs. Classes
Arrays vs. Classes
Arrays and Classes can both be used to organize a bunch of memory boxes.
int[] x = new int[]{100, 101, 102, 103};
public class planet {
public double mass;
public String name;
...
}
Arrays vs. Classes
Array indices can be computed at runtime.
int indexOfInterest = 1 + 1;
/* get contents of box #2 */
int k = x[indexOfInterest];�int j = x[-1 + 3];
Planet p = new Planet(6e24, "earth");
int[] x = new int[]{100, 101, 102, 103};
Both of these retrievals from an array are totally normal and work fine.
Arrays vs. Classes
Class member variable names CANNOT be computed and used at runtime.
String fieldOfInterest = "mass";
double m = p.fieldOfInterest;
double z = p[fieldOfInterest];
double a = p."mass";
double b = p["mass"];
Planet p = new Planet(6e24, "earth");
int[] x = new int[]{100, 101, 102, 103};
All of these attempts to use retrieve a field of interest are syntax errors in Java.
… if you reallllly want to do this, you can: https://goo.gl/JxpyLq
Another view
The only (easy) way to access a member of a class is with hard-coded dot notation.
The Java compiler does not treat text on either side of a dot as an expression, and thus it is not evaluated.
int k = x[indexOfInterest]; /* no problem */
double m = p.fieldOfInterest; /* won't work */
double z = p[fieldOfInterest]; /* won't work */
/* No (sane) way to use field of interest */
double w = p.mass; /* works fine */