Lecture 4: SLLists, Nested Classes, Sentinel Nodes

9/2/2020

public class IntList { public int first; public IntList rest; public IntList(int f, IntList r) { first = f; rest = r; } }

Improvement #1: Rebranding and Culling

public class IntNode { public int item; public IntNode next; public IntNode(int i, IntNode n) { item = i; next = n; } }

Improvement #2: Bureaucracy

public class IntNode { public int item; public IntNode next; public IntNode(int i, IntNode n) { item = i; next = n; } } // An SLList is a list of integers, which hides the terrible truth of the nakedness within public class SLList { public IntNode first; public SLList(int x) { first = new IntNode(x, null); } // Adds x to the front of the list public void addFirst(int x) { first = new IntNode(x, first); } // Returns the first item in the list public int getFirst() { return first.item; } public static void main(String[] args) { // Creates a list of one integer, namely 10 SLList L = new SLList(10); L.addFirst(10); // Adds 10 to front of list L.addFirst(5); // Adds 5 to front of list int x = L.getFirst(); } }

The Basic SLList and Helper IntNode Class

A Potential SLList Danger

SLList L = new SLList(15); L.addFirst(10); L.first.next.next = L.first.next;
public class SLList { private IntNode first; public SLList(int x) { first = new IntNode(x, null); } // Adds x to the front of the list public void addFirst(int x) { first = new IntNode(x, first); } // Returns the first item in the list public int getFirst() { return first.item; } public static void main(String[] args) { // Creates a list of one integer, namely 10 SLList L = new SLList(10); L.addFirst(10); // Adds 10 to front of list L.addFirst(5); // Adds 5 to front of list int x = L.getFirst(); } }

Why Restrict Access?

Improvement #4: Nesting a Class

public class SLList { private static class IntNode { // static: never looks outwards public int item; public IntNode next; public IntNode(int i, IntNode n) { item = i; next = n; } } private IntNode first; public SLList(int x) { first = new IntNode(x, null); } // Adds x to the front of the list public void addFirst(int x) { first = new IntNode(x, first); } // Returns the first item in the list public int getFirst() { return first.item; } public static void main(String[] args) { // Creates a list of one integer, namely 10 SLList L = new SLList(10); L.addFirst(10); // Adds 10 to front of list L.addFirst(5); // Adds 5 to front of list int x = L.getFirst(); } }

Why Nested Classes?

Static Nested Classes

Adding More SLList Functionality

public class SLList { private static class IntNode { // static: never looks outwards public int item; public IntNode next; public IntNode(int i, IntNode n) { item = i; next = n; } } private IntNode first; public SLList(int x) { first = new IntNode(x, null); } // Adds x to the front of the list public void addFirst(int x) { first = new IntNode(x, first); } // Returns the first item in the list public int getFirst() { return first.item; } // Adds an item to the end of the list public void addLast(int x) { IntNode p = first; while (p.next != null) { p = p.next; } p.next = new IntNode(x, null); } // Returns the size of the list that starts at IntNode p private static int size(IntNode p) { if (p.next == null) { return 1; } return 1 + size(p.next); } public int size() { return size(first); } public static void main(String[] args) { // Creates a list of one integer, namely 10 SLList L = new SLList(10); L.addFirst(10); // Adds 10 to front of list L.addFirst(5); // Adds 5 to front of list L.addLast(20); System.out.println(L.size()) } }

Efficiency of Size

Improvement #5: Fast size()

public class SLList { private static class IntNode { // static: never looks outwards public int item; public IntNode next; public IntNode(int i, IntNode n) { item = i; next = n; } } private IntNode first; private int size; public SLList(int x) { first = new IntNode(x, null); size = 1; } // Adds x to the front of the list public void addFirst(int x) { first = new IntNode(x, first); size += 1; } // Returns the first item in the list public int getFirst() { return first.item; } // Adds an item to the end of the list public void addLast(int x) { size += 1; IntNode p = first; while (p.next != null) { p = p.next; } p.next = new IntNode(x, null); } public int size() { return size; } public static void main(String[] args) { // Creates a list of one integer, namely 10 SLList L = new SLList(10); L.addFirst(10); // Adds 10 to front of list L.addFirst(5); // Adds 5 to front of list L.addLast(20); System.out.println(L.size()) } }

Improvement #6a: Representing the Empty List

public class SLList { private static class IntNode { // static: never looks outwards public int item; public IntNode next; public IntNode(int i, IntNode n) { item = i; next = n; } } private IntNode first; private int size; // Creates an empty SLList public SLList() { first = null; size = 0; } public SLList(int x) { first = new IntNode(x, null); size = 1; } // Adds x to the front of the list public void addFirst(int x) { first = new IntNode(x, first); size += 1; } // Returns the first item in the list public int getFirst() { return first.item; } // Adds an item to the end of the list public void addLast(int x) { size = size + 1; if (first == null) { first = new IntNode(x, null); return; } IntNode p = first; while (p.next != null) { p = p.next; } p.next = new IntNode(x, null); } public int size() { return size; } public static void main(String[] args) { // Creates a list of one integer, namely 10 SLList L = new SLList(); L.addFirst(10); // Adds 10 to front of list L.addFirst(5); // Adds 5 to front of list L.addLast(20); System.out.println(L.size()) } }

Tip for Being a GOod Programmer: Keep Code Simple

addLast's Fundamental Problem

Improvement #6b: Representing the Empty List Use a Sentinel Node

public class SLList { private static class IntNode { // static: never looks outwards public int item; public IntNode next; public IntNode(int i, IntNode n) { item = i; next = n; } } // The first item (if it exists) is at sentinel.next private IntNode sentinel; private int size; // Creates an empty SLList public SLList() { sentinel = new IntNode(69, null); size = 0; } public SLList(int x) { sentinel = new IntNode(69, null); sentinel.next = new IntNode(x, null); size = 1; } // Adds x to the front of the list public void addFirst(int x) { sentinel.next = new IntNode(x, sentinel.next); size = size + 1; } // Returns the first item in the list public int getFirst() { return sentinel.next.item; } // Adds an item to the end of the list public void addLast(int x) { size = size + 1; IntNode p = sentinel; while (p.next != null) { p = p.next; } p.next = new IntNode(x, null); } public int size() { return size; } public static void main(String[] args) { // Creates a list of one integer, namely 10 SLList L = new SLList(); L.addFirst(10); // Adds 10 to front of list L.addFirst(5); // Adds 5 to front of list L.addLast(20); System.out.println(L.size()) } }

Sentinel Node

addLast (with Sentinel Node)

Invariants