diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.classpath b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.classpath
new file mode 100644
index 0000000..8e3d409
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.classpath
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.project b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.project
new file mode 100644
index 0000000..0632975
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.project
@@ -0,0 +1,17 @@
+
+
+ Lab11_TopoSort
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.settings/org.eclipse.core.resources.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.settings/org.eclipse.jdt.core.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..e71285a
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=11
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/src/CurricExamples.java b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/src/CurricExamples.java
new file mode 100644
index 0000000..94cb17a
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/src/CurricExamples.java
@@ -0,0 +1,92 @@
+import java.util.Arrays;
+import java.util.ArrayList;
+import tester.Tester;
+
+class Examples {
+ Course algo = new Course("Algorithms and Data");
+ Course compilers = new Course("Compilers");
+ Course compSys = new Course("Computer Systems");
+ Course database = new Course("Database Design");
+ Course fundies2 = new Course("Fundies 2");
+ Course fundies1 = new Course("Fundies 1");
+ Course parallelProcessing = new Course("Large-Scale Parallel Data Processing");
+ Course ooDesign = new Course("Object-Oriented Design");
+ Course languages = new Course("Programming Languages");
+ Course compTheory = new Course("Theory of Computation");
+
+ ArrayList schedule0 = new ArrayList();
+ ArrayList scheduleFull = new ArrayList(
+ Arrays.asList(fundies1, fundies2, database,
+ compSys, algo, parallelProcessing, ooDesign,
+ compTheory, languages, compilers));
+ ArrayList schedulePartial = new ArrayList(
+ Arrays.asList(fundies1, fundies2, database,
+ compSys, algo));
+ ArrayList scheduleMissing = new ArrayList(
+ Arrays.asList(fundies2, database,
+ compSys, algo, parallelProcessing, ooDesign,
+ compTheory, languages, compilers));
+ ArrayList scheduleWrongOrder = new ArrayList(
+ Arrays.asList(fundies1, fundies2, database,
+ compSys, parallelProcessing, algo, ooDesign,
+ compTheory, languages, compilers));
+
+ Curriculum curri0;
+ Curriculum curri1;
+
+ void init() {
+ // fundies1
+ this.database.addPrereq(fundies1);
+ this.fundies2.addPrereq(fundies1);
+ this.algo.addPrereq(fundies2);
+ this.compSys.addPrereq(fundies2);
+ this.ooDesign.addPrereq(fundies2);
+ this.compTheory.addPrereq(fundies2);
+ this.parallelProcessing.addPrereq(algo);
+ this.parallelProcessing.addPrereq(compSys);
+ this.languages.addPrereq(compTheory);
+ this.languages.addPrereq(ooDesign);
+ this.compilers.addPrereq(languages);
+
+ this.curri0 = new Curriculum();
+ this.curri1 = new Curriculum(new ArrayList(Arrays.asList(
+ algo, compilers, compSys, database, fundies1, fundies2,
+ parallelProcessing, ooDesign, languages, compTheory)));
+ }
+ void testProcess(Tester t) {
+ init();
+ t.checkExpect(curri1.process(new ArrayList(), fundies1),
+ new ArrayList(Arrays.asList(fundies1)));
+ t.checkExpect(curri1.process(new ArrayList(), fundies2),
+ new ArrayList(Arrays.asList(fundies1, fundies2)));
+ t.checkExpect(curri1.process(new ArrayList(), parallelProcessing),
+ new ArrayList(Arrays.asList(fundies1, fundies2, algo, compSys,
+ parallelProcessing)));
+ t.checkExpect(curri1.process(new ArrayList(), compilers),
+ new ArrayList(Arrays.asList(fundies1, fundies2, compTheory,
+ ooDesign, languages, compilers)));
+ }
+ void testComesAfterPrereq(Tester t) {
+ init();
+ t.checkExpect(curri1.comesAfterPrereqs(scheduleFull, fundies1), true);
+ t.checkExpect(curri1.comesAfterPrereqs(scheduleFull, compilers), true);
+ t.checkExpect(curri1.comesAfterPrereqs(scheduleMissing, fundies2), false);
+ t.checkExpect(curri1.comesAfterPrereqs(scheduleWrongOrder, fundies1), true);
+ t.checkExpect(curri1.comesAfterPrereqs(scheduleWrongOrder, parallelProcessing), true);
+ }
+ void testValidSchedule(Tester t) {
+ init();
+ t.checkExpect(curri1.validSchedule(schedule0), true);
+ t.checkExpect(curri1.validSchedule(scheduleFull), true);
+ t.checkExpect(curri1.validSchedule(schedulePartial), true);
+ t.checkExpect(curri1.validSchedule(scheduleMissing), false);
+ t.checkExpect(curri1.validSchedule(scheduleWrongOrder), true);
+ }
+ void testTopologicalSort(Tester t) {
+ init();
+ t.checkExpect(curri0.topSort(), new ArrayList());
+ t.checkExpect(curri1.topSort(), new ArrayList(Arrays.asList(
+ fundies1, fundies2, algo, compTheory, ooDesign, languages,
+ compilers, compSys, database, parallelProcessing)));
+ }
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/src/Curriculum.java b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/src/Curriculum.java
new file mode 100644
index 0000000..c8d6d26
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lab11_TopoSort/src/Curriculum.java
@@ -0,0 +1,73 @@
+import java.util.ArrayList;
+
+class Curriculum {
+ ArrayList courses;
+ Curriculum(ArrayList courses) {
+ this.courses = courses;
+ }
+ Curriculum() {
+ this(new ArrayList());
+ }
+ // EFFECT: adds another course to the set of known courses
+ void addCourse(Course c) {
+ this.courses.add(c);
+ }
+
+ // If this course is in processed, then do nothing;
+ // otherwise, process this course’s prereqs, then
+ // add it to processed
+ ArrayList process(ArrayList processed, Course c) {
+ if (!processed.contains(c)) {
+ // process this course’s prereqs
+ for (Course prereq : c.prereqs) {
+ this.process(processed, prereq);
+ }
+ // add only after all prereqs are processed
+ processed.add(c);
+ }
+ return processed;
+ }
+ // returns true if the provided Course appears in the schedule
+ // after all of its prerequisites are satisfied
+ boolean comesAfterPrereqs(ArrayList schedule, Course c) {
+ ArrayList allPrereqs = this.process(new ArrayList(), c);
+ for (Course prereq : allPrereqs) {
+ if (!schedule.contains(prereq)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ // returns true if the schedule is valid for all the courses in it.
+ boolean validSchedule(ArrayList schedule) {
+ for (Course c : schedule) {
+ if (!this.comesAfterPrereqs(schedule, c)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ // process every course in the given list with that result list.
+ // Once every course has been processed, return the result list.
+ ArrayList topSort() {
+ ArrayList response = new ArrayList();
+ for (Course c : this.courses) {
+ response = this.process(response, c);
+ }
+ return response;
+ }
+}
+
+class Course {
+ String name;
+ ArrayList prereqs;
+ Course(String name) {
+ this.name = name;
+ this.prereqs = new ArrayList();
+ }
+ // EFFECT: adds a course as a prereq to this one
+ void addPrereq(Course c) {
+ this.prereqs.add(c);
+ }
+ // add methods here
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.classpath b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.classpath
new file mode 100644
index 0000000..8e3d409
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.classpath
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.project b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.project
new file mode 100644
index 0000000..c96d5b4
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.project
@@ -0,0 +1,17 @@
+
+
+ Lect30_Graphs
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.settings/org.eclipse.core.resources.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.settings/org.eclipse.jdt.core.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..e71285a
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=11
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/Collections.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/Collections.java
new file mode 100644
index 0000000..eb19168
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/Collections.java
@@ -0,0 +1,45 @@
+import java.util.Deque;
+import java.util.ArrayDeque;
+
+// Represents a mutable collection of items
+interface ICollection {
+ // Is this collection empty?
+ boolean isEmpty();
+ // EFFECT: adds the item to the collection
+ void add(T item);
+ // Returns the first item of the collection
+ // EFFECT: removes that first item
+ T remove();
+}
+
+class Stack implements ICollection {
+ Deque contents;
+ Stack() {
+ this.contents = new ArrayDeque();
+ }
+ public boolean isEmpty() {
+ return this.contents.isEmpty();
+ }
+ public T remove() {
+ return this.contents.removeLast();
+ }
+ public void add(T item) {
+ this.contents.addFirst(item);
+ }
+}
+
+class Queue implements ICollection {
+ Deque contents;
+ Queue() {
+ this.contents = new ArrayDeque();
+ }
+ public boolean isEmpty() {
+ return this.contents.isEmpty();
+ }
+ public T remove() {
+ return this.contents.removeLast();
+ }
+ public void add(T item) {
+ this.contents.addLast(item); // NOTE: Different from Stack!
+ }
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/Graph.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/Graph.java
new file mode 100644
index 0000000..5c6f639
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/Graph.java
@@ -0,0 +1,162 @@
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.ArrayDeque;
+
+class Vertex {
+ //... any data about vertices, such as people's names, or place's GPS coordinates ...
+ String name;
+ ArrayList outEdges; // edges from this node
+
+ Vertex(String name, ArrayList outEdges) {
+ this.name = name;
+ this.outEdges = outEdges;
+ }
+ Vertex(String name, Edge outEdge) {
+ this(name, new ArrayList(Arrays.asList(outEdge)));
+ }
+ Vertex(String name) {
+ this(name, new ArrayList());
+ }
+ void setEdge(Edge edge) {
+ this.outEdges.add(edge);
+ }
+
+ boolean hasPathTo(Vertex dest) {
+ ArrayList checked = new ArrayList();
+
+ return this.hasPathToHelp(dest, checked);
+ }
+ boolean hasPathToHelp(Vertex dest, ArrayList checked) {
+ for (Edge edge : this.outEdges) {
+ if (checked.contains(edge)) {
+ continue;
+ }
+ checked.add(edge);
+ if (edge.to == dest ||
+ edge.to.hasPathToHelp(dest, checked)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+class Edge {
+ Vertex from;
+ Vertex to;
+ int weight;
+
+ Edge(Vertex from, Vertex to, int weight) {
+ this.from = from;
+ this.to = to;
+ this.weight = weight;
+ from.setEdge(this);
+ }
+ Edge(Vertex from, Vertex to) {
+ this(from, to, 1);
+ }
+}
+
+class Graph {
+ ArrayList allVertices;
+
+ Graph(ArrayList allVertices) {
+ this.allVertices = allVertices;
+ }
+ Graph() {
+ this.allVertices = new ArrayList();
+ }
+
+ ArrayList getEdges() {
+ ArrayList response = new ArrayList();
+ for (Vertex vertex : this.allVertices) {
+ for (Edge edge : vertex.outEdges) {
+ if (!(response.contains(edge))) {
+ response.add(edge);
+ }
+ }
+ }
+ return response;
+ }
+
+ boolean hasPathBetween(Vertex from, Vertex to) {
+ Deque alreadySeen = new ArrayDeque();
+ Deque worklist = new ArrayDeque();
+
+ // Initialize the worklist with the from vertex
+ worklist.addFirst(from);
+ // As long as the worklist isn't empty...
+ while (!worklist.isEmpty()) {
+ Vertex next = worklist.removeLast();
+ if (next.equals(to)) {
+ return true; // Success!
+ } else if (alreadySeen.contains(next)) {
+ // do nothing: we've already seen this one
+ } else {
+ // add all the neighbors of next to the worklist for further processing
+ for (Edge e : next.outEdges) {
+ worklist.addFirst(e.to);
+ }
+ // add next to alreadySeen, since we're done with it
+ alreadySeen.addFirst(next);
+ }
+ }
+ // We haven't found the to vertex, and there are no more to try
+ return false;
+ }
+ boolean breadthFistSearch(Vertex from, Vertex to) {
+ return searchHelp(from, to, new Queue());
+ }
+ boolean depthFirstSearch(Vertex from, Vertex to) {
+ return searchHelp(from, to, new Stack());
+ }
+ boolean searchHelp(Vertex from, Vertex to, ICollection worklist) {
+ Deque alreadySeen = new ArrayDeque();
+
+ // Initialize the worklist with the from vertex
+ worklist.add(from);
+ // As long as the worklist isn't empty...
+ while (!worklist.isEmpty()) {
+ Vertex next = worklist.remove();
+ if (next.equals(to)) {
+ return true; // Success!
+ } else if (alreadySeen.contains(next)) {
+ // do nothing: we've already seen this one
+ } else {
+ // add all the neighbors of next to the worklist for further processing
+ for (Edge e : next.outEdges) {
+ worklist.add(e.to);
+ }
+ // add next to alreadySeen, since we're done with it
+ alreadySeen.addFirst(next);
+ }
+ }
+ // We haven't found the to vertex, and there are no more to try
+ return false;
+ }
+ Deque findPath(Vertex from, Vertex to, ICollection worklist) {
+ Deque alreadySeen = new ArrayDeque();
+
+ // Initialize the worklist with the from vertex
+ worklist.add(from);
+ // As long as the worklist isn't empty...
+ while (!worklist.isEmpty()) {
+ Vertex next = worklist.remove();
+ if (next.equals(to)) {
+ return alreadySeen; // Success!
+ } else if (alreadySeen.contains(next)) {
+ // do nothing: we've already seen this one
+ } else {
+ // add all the neighbors of next to the worklist for further processing
+ for (Edge e : next.outEdges) {
+ worklist.add(e.to);
+ }
+ // add next to alreadySeen, since we're done with it
+ alreadySeen.addFirst(next);
+ }
+ }
+ // We haven't found the to vertex, and there are no more to try
+ throw new RuntimeException("Could not find a valid path");
+ }
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/GraphExamples.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/GraphExamples.java
new file mode 100644
index 0000000..c9c9d47
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect30_Graphs/src/GraphExamples.java
@@ -0,0 +1,113 @@
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.ArrayDeque;
+import tester.Tester;
+
+class Examples {
+ Vertex v0;
+ Vertex v1;
+ Vertex v2;
+ Vertex v3;
+ Vertex vAlone;
+ ArrayList linearVerts;
+
+ Edge e0;
+ Edge e1;
+ Edge e2;
+ ArrayList linearEdges;
+
+ Vertex vA;
+ Vertex vB;
+ Vertex vC;
+ Vertex vD;
+ Vertex vE;
+ ArrayList circVerts;
+
+ Edge eAB;
+ Edge eBD;
+ Edge eBC;
+ Edge eCA;
+ Edge eEB;
+ ArrayList circEdges;
+
+ Graph gEmpty;
+ Graph gLinear;
+ Graph gCircular;
+
+ void init() {
+ v0 = new Vertex("0");
+ v1 = new Vertex("1");
+ v2 = new Vertex("2");
+ v3 = new Vertex("3");
+ vAlone = new Vertex("Alone");
+
+ e0 = new Edge(v0, v1);
+ e1 = new Edge(v1, v2);
+ e2 = new Edge(v2, v3);
+
+ linearVerts = new ArrayList(Arrays.asList(v0, v1, v2));
+ linearEdges = new ArrayList(Arrays.asList(e0, e1, e2));
+
+ vA = new Vertex("A");
+ vB = new Vertex("B");
+ vC = new Vertex("C");
+ vD = new Vertex("D");
+ vE = new Vertex("E");
+
+ eAB = new Edge(vA, vB);
+ eBD = new Edge(vB, vD);
+ eBC = new Edge(vB, vC);
+ eCA = new Edge(vC, vA);
+ eEB = new Edge(vE, vB);
+
+ circVerts = new ArrayList(
+ Arrays.asList(vA, vB, vC, vD, vE));
+ circEdges = new ArrayList(
+ Arrays.asList(eAB, eBD, eBC, eCA, eEB));
+
+ gEmpty = new Graph();
+ gLinear = new Graph(linearVerts);
+ gCircular = new Graph(circVerts);
+ }
+
+ void testGetEdges(Tester t) {
+ init();
+ t.checkExpect(this.gLinear.getEdges(), linearEdges);
+ t.checkExpect(this.gCircular.getEdges(), circEdges);
+ }
+ void testHasPath(Tester t) {
+ init();
+ t.checkExpect(this.v0.hasPathTo(v3), true);
+ t.checkExpect(this.v0.hasPathTo(vAlone), false);
+ t.checkExpect(this.vA.hasPathTo(vC), true);
+ t.checkExpect(this.vA.hasPathTo(vE), false);
+ t.checkExpect(this.gLinear.hasPathBetween(v0, v3), true);
+ t.checkExpect(this.gLinear.hasPathBetween(v0, vAlone), false);
+ t.checkExpect(this.gCircular.hasPathBetween(vA, vC), true);
+ t.checkExpect(this.gCircular.hasPathBetween(vA, vD), true);
+ t.checkExpect(this.gCircular.hasPathBetween(vA, vE), false);
+ t.checkExpect(this.gCircular.hasPathBetween(vE, vA), true);
+ }
+ void testSearch(Tester t) {
+ init();
+ t.checkExpect(this.gLinear.breadthFistSearch(v0, v3), true);
+ t.checkExpect(this.gLinear.breadthFistSearch(v0, vAlone), false);
+ t.checkExpect(this.gCircular.breadthFistSearch(vA, vC), true);
+ t.checkExpect(this.gCircular.breadthFistSearch(vA, vD), true);
+ t.checkExpect(this.gCircular.breadthFistSearch(vA, vE), false);
+ t.checkExpect(this.gCircular.breadthFistSearch(vE, vA), true);
+
+ t.checkExpect(this.gLinear.depthFirstSearch(v0, v3), true);
+ t.checkExpect(this.gLinear.depthFirstSearch(v0, vAlone), false);
+ t.checkExpect(this.gCircular.depthFirstSearch(vA, vC), true);
+ t.checkExpect(this.gCircular.depthFirstSearch(vA, vD), true);
+ t.checkExpect(this.gCircular.depthFirstSearch(vA, vE), false);
+ t.checkExpect(this.gCircular.depthFirstSearch(vE, vA), true);
+ }
+ void testFindPath(Tester t) {
+ init();
+ t.checkExpect(this.gLinear.findPath(v0, v3, new Queue()),
+ new ArrayDeque(Arrays.asList(v3, v2, v1, v0)));
+ }
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.classpath b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.classpath
new file mode 100644
index 0000000..8e3d409
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.classpath
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.project b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.project
new file mode 100644
index 0000000..5581f2d
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.project
@@ -0,0 +1,17 @@
+
+
+ Lect31_DijkstrasAlgorithm
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.settings/org.eclipse.core.resources.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.settings/org.eclipse.jdt.core.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..e71285a
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=11
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Collections.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Collections.java
new file mode 100644
index 0000000..32b2b20
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Collections.java
@@ -0,0 +1,126 @@
+import java.util.Deque;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+
+// Represents a mutable collection of items
+interface ICollection {
+ // Is this collection empty?
+ boolean isEmpty();
+ // EFFECT: adds the item to the collection
+ void add(T item);
+ // Returns the first item of the collection
+ // EFFECT: removes that first item
+ T remove();
+}
+
+// first in first out
+class Stack implements ICollection {
+ Deque contents;
+ Stack() {
+ this.contents = new ArrayDeque();
+ }
+ public boolean isEmpty() {
+ return this.contents.isEmpty();
+ }
+ public T remove() {
+ return this.contents.removeLast();
+ }
+ public void add(T item) {
+ this.contents.addFirst(item);
+ }
+}
+
+// last in last out
+class Queue implements ICollection {
+ Deque contents;
+ Queue() {
+ this.contents = new ArrayDeque();
+ }
+ public boolean isEmpty() {
+ return this.contents.isEmpty();
+ }
+ public T remove() {
+ return this.contents.removeLast();
+ }
+ public void add(T item) {
+ this.contents.addLast(item); // NOTE: Different from Stack!
+ }
+}
+
+// highest priority out
+class PriorityQueue implements ICollection {
+ ArrayList heap;
+ IComparator comp;
+ PriorityQueue(ArrayList inputList, IComparator comp) {
+ this.comp = comp;
+ buildHeap(inputList);
+ }
+ PriorityQueue(IComparator comp) {
+ this(new ArrayList(), comp);
+ }
+ void buildHeap(ArrayList inputList) {
+ this.heap = inputList;
+ for (int i = inputList.size() - 1; i >= 0; i--) {
+ this.downHeap(i);
+ }
+ }
+ // swaps the parent and child items
+ void swap(int parentIndex, int childIndex) {
+ T temp = heap.get(parentIndex);
+ heap.set(parentIndex, heap.get(childIndex));
+ heap.set(childIndex, temp);
+ }
+ // recursively uses comp to compare child with parent
+ // and swaps if child is higher priority
+ void upHeap(int childIndex) {
+ int parentIndex = (childIndex - 1) / 2;
+ // comp will return >0 if left has higher priority than right
+ // ergo swap when comp returns <0
+ if (comp.compare(heap.get(parentIndex), heap.get(childIndex)) < 0) {
+ this.swap(parentIndex, childIndex);
+ this.upHeap(parentIndex);
+ }
+ }
+ // recursively uses comp to compare parent with children
+ // and swaps if child is higher priority
+ void downHeap(int parentIndex) {
+ this.downHeapMaxDepth(parentIndex, this.heap.size());
+ }
+ void downHeapMaxDepth(int parentIndex, int maxDepthIndex) {
+ int leftChildIndex = 2 * parentIndex + 1;
+ int rightChildIndex = 2 * parentIndex + 2;
+ if (rightChildIndex < maxDepthIndex) {
+ if (comp.compare(heap.get(leftChildIndex), heap.get(rightChildIndex)) > 0) {
+ if (comp.compare(heap.get(parentIndex), heap.get(leftChildIndex)) < 0) {
+ this.swap(parentIndex, leftChildIndex);
+ this.downHeapMaxDepth(leftChildIndex, maxDepthIndex);
+ }
+ } else if (comp.compare(heap.get(parentIndex), heap.get(rightChildIndex)) < 0) {
+ this.swap(parentIndex, rightChildIndex);
+ this.downHeapMaxDepth(rightChildIndex, maxDepthIndex);
+ }
+ } else if (leftChildIndex < maxDepthIndex) {
+ if (comp.compare(heap.get(parentIndex), heap.get(leftChildIndex)) < 0) {
+ this.swap(parentIndex, leftChildIndex);
+ this.downHeapMaxDepth(leftChildIndex, maxDepthIndex);
+ }
+ }
+ }
+
+ // Interface methods
+ public boolean isEmpty() {
+ return this.heap.isEmpty();
+ }
+ public void add(T item) {
+ this.heap.add(item);
+ this.upHeap(heap.size() - 1);
+ }
+ public T remove() {
+ int lastIndex = this.heap.size() - 1;
+ this.swap(0, lastIndex);
+ T response = this.heap.remove(lastIndex);
+ this.downHeap(0);
+ return response;
+ }
+
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Comparator.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Comparator.java
new file mode 100644
index 0000000..df6feb4
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Comparator.java
@@ -0,0 +1,51 @@
+interface IPred {
+ boolean apply(T t);
+}
+
+interface IFunc {
+ R apply(A arg);
+}
+
+interface IFunc2 {
+ R apply(A1 arg1, A2 arg2);
+}
+
+interface IComparator {
+ // Returns a negative number if t1 priority is less than t2 priority==-
+ int compare(T t1, T t2);
+}
+
+class ParentLargerInteger implements IComparator {
+ // returns true (>0) if left has higher priority (larger int)
+ public int compare(Integer left, Integer right) {
+ return left - right;
+ }
+}
+
+class ParentSmallerInteger implements IComparator {
+ // returns true (>0) if left has a higher priority (smaller int)
+ public int compare(Integer left, Integer right) {
+ return right - left;
+ }
+}
+
+class HigherVertexWeight implements IComparator {
+ // returns true (>0) if left has a higher priority (larger weight)
+ public int compare(Vertex left, Vertex right) {
+ return left.weight - right.weight;
+ }
+}
+
+class SmallerVertexWeight implements IComparator {
+ // returns true (>0) if left has a higher priority (smaller weight)
+ public int compare(Vertex left, Vertex right) {
+ return right.weight - left.weight;
+ }
+}
+
+class SmallerPathCost implements IComparator {
+ // returns true (>0) if left has a lower cost (cumulative cost)
+ public int compare(Path left, Path right) {
+ return right.weight - left.weight;
+ }
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Graph.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Graph.java
new file mode 100644
index 0000000..0a0c1b9
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/Graph.java
@@ -0,0 +1,230 @@
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.ArrayDeque;
+
+class Vertex {
+ //... any data about vertices, such as people's names, or place's GPS coordinates ...
+ String name;
+ int weight;
+ ArrayList outEdges; // edges from this node
+
+ Vertex(String name, int weight, ArrayList outEdges) {
+ this.name = name;
+ this.weight = weight;
+ this.outEdges = outEdges;
+ }
+ Vertex(String name, Edge outEdge) {
+ this(name, 1, new ArrayList(Arrays.asList(outEdge)));
+ }
+ Vertex(String name, int weight) {
+ this(name, weight, new ArrayList());
+ }
+ Vertex(String name) {
+ this(name, 1, new ArrayList());
+ }
+
+ void setEdge(Edge edge) {
+ this.outEdges.add(edge);
+ }
+
+ boolean hasPathTo(Vertex dest) {
+ ArrayList checked = new ArrayList();
+ return this.hasPathToHelp(dest, checked);
+ }
+ boolean hasPathToHelp(Vertex dest, ArrayList checked) {
+ for (Edge edge : this.outEdges) {
+ if (checked.contains(edge)) {
+ continue;
+ }
+ checked.add(edge);
+ if (edge.to == dest ||
+ edge.to.hasPathToHelp(dest, checked)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+class Edge {
+ Vertex from;
+ Vertex to;
+ int weight;
+
+ Edge(Vertex from, Vertex to, int weight) {
+ this.from = from;
+ this.to = to;
+ this.weight = weight;
+ from.setEdge(this);
+ }
+ Edge(Vertex from, Vertex to) {
+ this(from, to, 1);
+ }
+}
+
+class Path {
+ ArrayList route;
+ Vertex next;
+ int weight;
+ Path(ArrayList route, Vertex next, int weight) {
+ this.route = route;
+ this.next = next;
+ this.weight = weight;
+ }
+ Path(Vertex v) {
+ this(new ArrayList(), v, v.weight);
+ }
+ Path() {
+ this(new ArrayList(), null, 0);
+ }
+
+ void addNext(Vertex v) {
+ this.route.add(this.next);
+ this.weight = this.weight + v.weight;
+ this.next = v;
+ }
+ Path branchPath(Vertex v, int edgeWeight) {
+ // create copy of this
+ Path copy = new Path(new ArrayList(this.route), this.next,
+ this.weight + edgeWeight);
+ copy.addNext(v);
+ return copy;
+ }
+ ArrayList getFullRoute() {
+ route.add(this.next);
+ return this.route;
+ }
+}
+
+class Graph {
+ ArrayList allVertices;
+
+ Graph(ArrayList allVertices) {
+ this.allVertices = allVertices;
+ }
+ Graph() {
+ this.allVertices = new ArrayList();
+ }
+
+ ArrayList getEdges() {
+ ArrayList response = new ArrayList();
+ for (Vertex vertex : this.allVertices) {
+ for (Edge edge : vertex.outEdges) {
+ if (!(response.contains(edge))) {
+ response.add(edge);
+ }
+ }
+ }
+ return response;
+ }
+
+ boolean hasPathBetween(Vertex from, Vertex to) {
+ Deque alreadySeen = new ArrayDeque();
+ Deque worklist = new ArrayDeque();
+
+ // Initialize the worklist with the from vertex
+ worklist.addFirst(from);
+ // As long as the worklist isn't empty...
+ while (!worklist.isEmpty()) {
+ Vertex next = worklist.removeLast();
+ if (next.equals(to)) {
+ return true; // Success!
+ } else if (alreadySeen.contains(next)) {
+ // do nothing: we've already seen this one
+ } else {
+ // add all the neighbors of next to the worklist for further processing
+ for (Edge e : next.outEdges) {
+ worklist.addFirst(e.to);
+ }
+ // add next to alreadySeen, since we're done with it
+ alreadySeen.addFirst(next);
+ }
+ }
+ // We haven't found the to vertex, and there are no more to try
+ return false;
+ }
+ boolean breadthFirstSearch(Vertex from, Vertex to) {
+ return searchHelp(from, to, new Queue());
+ }
+ boolean depthFirstSearch(Vertex from, Vertex to) {
+ return searchHelp(from, to, new Stack());
+ }
+ boolean weightedSearch(Vertex from, Vertex to, IComparator comp) {
+ return searchHelp(from, to, new PriorityQueue(comp));
+ }
+ boolean searchHelp(Vertex from, Vertex to, ICollection worklist) {
+ Deque alreadySeen = new ArrayDeque();
+
+ // Initialize the worklist with the from vertex
+ worklist.add(from);
+ // As long as the worklist isn't empty...
+ while (!worklist.isEmpty()) {
+ Vertex next = worklist.remove();
+ if (next.equals(to)) {
+ return true; // Success!
+ } else if (alreadySeen.contains(next)) {
+ // do nothing: we've already seen this one
+ } else {
+ // add all the neighbors of next to the worklist for further processing
+ for (Edge e : next.outEdges) {
+ worklist.add(e.to);
+ }
+ // add next to alreadySeen, since we're done with it
+ alreadySeen.addFirst(next);
+ }
+ }
+ // We haven't found the to vertex, and there are no more to try
+ return false;
+ }
+ // ArrayList leastCostPath(Vertex from, Vertex to) {
+ // ICollection weightedPaths = new PriorityQueue(new SmallerPathCost());
+ // Deque alreadySeen = new ArrayDeque();
+ //
+ // // Initialize the worklist with the from vertex'
+ // weightedPaths.add(new Path(from));
+ // // As long as the worklist isn't empty...
+ // while (!weightedPaths.isEmpty()) {
+ // Path cheapestPath = weightedPaths.remove();
+ // if (cheapestPath.next.equals(to)) {
+ // // we need to add cheapestPath.next to returned list
+ // return cheapestPath.getFullRoute(); // Success!
+ // } else if (alreadySeen.contains(cheapestPath.next)) {
+ // // do nothing: we've already seen this one
+ // } else {
+ // // add all the neighbors of next to the worklist for further processing
+ // for (Edge e : cheapestPath.next.outEdges) {
+ // weightedPaths.add(cheapestPath.branchPath(e.to, e.weight));
+ // }
+ // // add next to alreadySeen, since we're done with it
+ // alreadySeen.add(cheapestPath.next);
+ // }
+ // }
+ // // We haven't found the to vertex, and there are no more to try
+ // throw new RuntimeException("Cannot find valid route");
+ // }
+ Deque findPath(Vertex from, Vertex to, ICollection worklist) {
+ Deque alreadySeen = new ArrayDeque();
+
+ // Initialize the worklist with the from vertex
+ worklist.add(from);
+ // As long as the worklist isn't empty...
+ while (!worklist.isEmpty()) {
+ Vertex next = worklist.remove();
+ if (next.equals(to)) {
+ return alreadySeen; // Success!
+ } else if (alreadySeen.contains(next)) {
+ // do nothing: we've already seen this one
+ } else {
+ // add all the neighbors of next to the worklist for further processing
+ for (Edge e : next.outEdges) {
+ worklist.add(e.to);
+ }
+ // add next to alreadySeen, since we're done with it
+ alreadySeen.addFirst(next);
+ }
+ }
+ // We haven't found the to vertex, and there are no more to try
+ throw new RuntimeException("Could not find a valid path");
+ }
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/GraphExamples.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/GraphExamples.java
new file mode 100644
index 0000000..895553d
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/GraphExamples.java
@@ -0,0 +1,153 @@
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.Arrays;
+import java.util.ArrayDeque;
+import tester.Tester;
+
+class GraphExamples {
+ Vertex v0;
+ Vertex v1;
+ Vertex v2;
+ Vertex v3;
+ Vertex vAlone;
+ ArrayList linearVerts;
+
+ Edge e0;
+ Edge e1;
+ Edge e2;
+ ArrayList linearEdges;
+
+ Vertex vA;
+ Vertex vB;
+ Vertex vC;
+ Vertex vD;
+ Vertex vE;
+ ArrayList circVerts;
+
+ Edge eAB;
+ Edge eBD;
+ Edge eBC;
+ Edge eCA;
+ Edge eEB;
+ ArrayList circEdges;
+
+ Vertex wA;
+ Vertex wB;
+ Vertex wC;
+ Vertex wD;
+ Vertex wE;
+ Vertex wF;
+ ArrayList weightedVerts;
+
+ Edge wAB;
+ Edge wBC;
+ Edge wCD;
+ Edge wDE;
+ Edge wEF;
+ Edge wAF;
+ ArrayList weightedEdges;
+
+ Graph gEmpty;
+ Graph gLinear;
+ Graph gCircular;
+ Graph gWeighted;
+
+ void init() {
+ v0 = new Vertex("0");
+ v1 = new Vertex("1");
+ v2 = new Vertex("2");
+ v3 = new Vertex("3");
+ e0 = new Edge(v0, v1);
+ e1 = new Edge(v1, v2);
+ e2 = new Edge(v2, v3);
+ linearVerts = new ArrayList(Arrays.asList(v0, v1, v2));
+ linearEdges = new ArrayList(Arrays.asList(e0, e1, e2));
+
+ vA = new Vertex("A");
+ vB = new Vertex("B");
+ vC = new Vertex("C");
+ vD = new Vertex("D");
+ vE = new Vertex("E");
+ eAB = new Edge(vA, vB);
+ eBD = new Edge(vB, vD);
+ eBC = new Edge(vB, vC);
+ eCA = new Edge(vC, vA);
+ eEB = new Edge(vE, vB);
+ circVerts = new ArrayList(
+ Arrays.asList(vA, vB, vC, vD, vE));
+ circEdges = new ArrayList(
+ Arrays.asList(eAB, eBD, eBC, eCA, eEB));
+
+ wA = new Vertex("A");
+ wB = new Vertex("B");
+ wC = new Vertex("C");
+ wD = new Vertex("D");
+ wE = new Vertex("E");
+ wF = new Vertex("F");
+ wAB = new Edge(wA, wB, 1);
+ wBC = new Edge(wB, wC, 1);
+ wCD = new Edge(wC, wD, 1);
+ wDE = new Edge(wD, wE, 1);
+ wEF = new Edge(wE, wF, 1);
+ wAF = new Edge(wA, wF, 3);
+ weightedVerts = new ArrayList(
+ Arrays.asList(wA, wB, wC, wD, wE, wF));
+ weightedEdges = new ArrayList(
+ Arrays.asList(wAB, wBC, wCD, wDE, wEF, wAF));
+
+ vAlone = new Vertex("Alone");
+ gEmpty = new Graph();
+ gLinear = new Graph(linearVerts);
+ gCircular = new Graph(circVerts);
+ gWeighted = new Graph(weightedVerts);
+ }
+ void testGetEdges(Tester t) {
+ init();
+ t.checkExpect(this.gLinear.getEdges(), linearEdges);
+ t.checkExpect(this.gCircular.getEdges(), circEdges);
+ }
+ void testHasPath(Tester t) {
+ init();
+ t.checkExpect(this.v0.hasPathTo(v3), true);
+ t.checkExpect(this.v0.hasPathTo(vAlone), false);
+ t.checkExpect(this.vA.hasPathTo(vC), true);
+ t.checkExpect(this.vA.hasPathTo(vE), false);
+ t.checkExpect(this.gLinear.hasPathBetween(v0, v3), true);
+ t.checkExpect(this.gLinear.hasPathBetween(v0, vAlone), false);
+ t.checkExpect(this.gCircular.hasPathBetween(vA, vC), true);
+ t.checkExpect(this.gCircular.hasPathBetween(vA, vD), true);
+ t.checkExpect(this.gCircular.hasPathBetween(vA, vE), false);
+ t.checkExpect(this.gCircular.hasPathBetween(vE, vA), true);
+ }
+ void testSearch(Tester t) {
+ init();
+ t.checkExpect(this.gLinear.breadthFirstSearch(v0, v3), true);
+ t.checkExpect(this.gLinear.breadthFirstSearch(v0, vAlone), false);
+ t.checkExpect(this.gCircular.breadthFirstSearch(vA, vC), true);
+ t.checkExpect(this.gCircular.breadthFirstSearch(vA, vD), true);
+ t.checkExpect(this.gCircular.breadthFirstSearch(vA, vE), false);
+ t.checkExpect(this.gCircular.breadthFirstSearch(vE, vA), true);
+
+ t.checkExpect(this.gLinear.depthFirstSearch(v0, v3), true);
+ t.checkExpect(this.gLinear.depthFirstSearch(v0, vAlone), false);
+ t.checkExpect(this.gCircular.depthFirstSearch(vA, vC), true);
+ t.checkExpect(this.gCircular.depthFirstSearch(vA, vD), true);
+ t.checkExpect(this.gCircular.depthFirstSearch(vA, vE), false);
+ t.checkExpect(this.gCircular.depthFirstSearch(vE, vA), true);
+
+ IComparator smallerWeight = new SmallerVertexWeight();
+ t.checkExpect(this.gWeighted.weightedSearch(wA, wF, smallerWeight), true);
+ t.checkExpect(this.gWeighted.weightedSearch(wA, wB, smallerWeight), true);
+ t.checkExpect(this.gWeighted.weightedSearch(wF, wA, smallerWeight), false);
+ }
+ // void testWeightedSearch(Tester t) {
+ // init();
+ // ArrayList ans = new ArrayList();
+ // ans.add(wA);
+ // ans.add(wF);
+ // t.checkExpect(this.gWeighted.leastCostPath(wA, wF), ans);
+ // wAF.weight = 10;
+ // t.checkExpect(this.gWeighted.leastCostPath(wA, wF),
+ // new ArrayList(Arrays.asList(wA, wB, wC, wD, wE, wF)));
+ // }
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/PQExamples.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/PQExamples.java
new file mode 100644
index 0000000..bda801f
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect31_DijkstrasAlgorithm/src/PQExamples.java
@@ -0,0 +1,142 @@
+import java.util.ArrayList;
+import java.util.Arrays;
+import tester.Tester;
+
+class PQExamples {
+ ArrayList unsortedList;
+ ArrayList upHeapedList;
+ ArrayList downHeapedList;
+ ArrayList sortedList;
+ ArrayList worstCaseList;
+
+ PriorityQueue heapEmptyParentSmaller;
+ PriorityQueue heapPopulatedParentSmaller;
+ PriorityQueue heapGreaterTop;
+
+ IComparator compParentGreater;
+ IComparator compParentSmaller;
+
+ void init() {
+ unsortedList = new ArrayList(
+ Arrays.asList(10, 60, 15, 30, 50, 40, 20, 80, 20, 50));
+ downHeapedList = new ArrayList(
+ Arrays.asList(10, 20, 15, 30, 50, 40, 20, 80, 60, 50));
+ upHeapedList = new ArrayList(
+ Arrays.asList(80, 60, 40, 50, 50, 15, 20, 10, 20, 30));
+ worstCaseList = new ArrayList(
+ Arrays.asList(9, 8, 7, 6, 5, 4, 3, 2, 1));
+
+ compParentGreater = new ParentLargerInteger();
+ compParentSmaller = new ParentSmallerInteger();
+ heapEmptyParentSmaller = new PriorityQueue(compParentSmaller);
+ heapPopulatedParentSmaller = new PriorityQueue(unsortedList, compParentSmaller);
+ }
+ void testSwap(Tester t) {
+ init();
+ t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 0);
+ heapEmptyParentSmaller.heap.add(10);
+ heapEmptyParentSmaller.heap.add(20);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 2);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 10);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 20);
+ heapEmptyParentSmaller.swap(0, 1);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 2);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 20);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 10);
+ }
+ void testUpHeap(Tester t) {
+ init();
+ t.checkExpect(heapEmptyParentSmaller.heap.size(), 0);
+ heapEmptyParentSmaller.heap.add(20);
+ heapEmptyParentSmaller.upHeap(0);
+ t.checkExpect(heapEmptyParentSmaller.heap.size(), 1);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(0), 20);
+ heapEmptyParentSmaller.heap.add(10);
+ heapEmptyParentSmaller.upHeap(1);
+ t.checkExpect(heapEmptyParentSmaller.heap.size(), 2);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(0), 10);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(1), 20);
+ heapEmptyParentSmaller.heap.add(30);
+ heapEmptyParentSmaller.upHeap(2);
+ t.checkExpect(heapEmptyParentSmaller.heap.size(), 3);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(0), 10);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(1), 20);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(2), 30);
+ heapEmptyParentSmaller.heap.add(20);
+ heapEmptyParentSmaller.upHeap(3);
+ t.checkExpect(heapEmptyParentSmaller.heap.size(), 4);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(0), 10);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(1), 20);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(2), 30);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(3), 20);
+ heapEmptyParentSmaller.heap.add(20);
+ heapEmptyParentSmaller.upHeap(4);
+ heapEmptyParentSmaller.heap.add(20);
+ heapEmptyParentSmaller.upHeap(5);
+ t.checkExpect(heapEmptyParentSmaller.heap.size(), 6);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(0), 10);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(1), 20);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(2), 20);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(3), 20);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(4), 20);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(5), 30);
+ }
+ void testDownHeap(Tester t) {
+ init();
+ t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 0);
+ heapEmptyParentSmaller.heap.add(0, 50);
+ heapEmptyParentSmaller.downHeap(0);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 1);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 50);
+ heapEmptyParentSmaller.heap.add(0, 40);
+ heapEmptyParentSmaller.downHeap(0);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 40);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 50);
+ heapEmptyParentSmaller.heap.add(0, 60);
+ heapEmptyParentSmaller.downHeap(0);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 40);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 60);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(2), 50);
+ heapEmptyParentSmaller.heap.add(0, 30);
+ heapEmptyParentSmaller.downHeap(0);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 30);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 40);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(2), 60);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(3), 50);
+ heapEmptyParentSmaller.heap.add(0, 70);
+ heapEmptyParentSmaller.downHeap(0);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 30);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 50);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(2), 40);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(3), 60);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(4), 70);
+ }
+ void testBuildDownHeap(Tester t) {
+ init();
+ heapEmptyParentSmaller.buildHeap(unsortedList);
+ t.checkExpect(heapEmptyParentSmaller.heap, downHeapedList);
+ ArrayList worstDownList = new ArrayList(Arrays.asList(
+ 1, 2, 3, 6, 5, 4, 7, 8, 9));
+ init();
+ heapEmptyParentSmaller.buildHeap(worstCaseList);
+ t.checkExpect(this.heapEmptyParentSmaller.heap, worstDownList);
+ }
+ void testAdd(Tester t) {
+ init();
+ ArrayList addedList_90 = new ArrayList(
+ Arrays.asList(10, 20, 15, 30, 50, 40, 20, 80, 60, 50, 90));
+ ArrayList addedList_9005 = new ArrayList(
+ Arrays.asList(5, 20, 10, 30, 50, 15, 20, 80, 60, 50, 90, 40));
+ this.heapPopulatedParentSmaller.add(90);
+ t.checkExpect(this.heapPopulatedParentSmaller.heap, addedList_90);
+ this.heapPopulatedParentSmaller.add(5);
+ t.checkExpect(this.heapPopulatedParentSmaller.heap, addedList_9005);
+ }
+ void testRemove(Tester t) {
+ init();
+ t.checkExpect(this.heapPopulatedParentSmaller.remove(), 10);
+ ArrayList removedList = new ArrayList(
+ Arrays.asList(15, 20, 20, 30, 50, 40, 50, 80, 60));
+ t.checkExpect(this.heapPopulatedParentSmaller.heap, removedList);
+ }
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.classpath b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.classpath
new file mode 100644
index 0000000..8e3d409
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.classpath
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.project b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.project
new file mode 100644
index 0000000..4bbb79a
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.project
@@ -0,0 +1,17 @@
+
+
+ Lect32_SpanningTrees
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.settings/org.eclipse.core.resources.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.settings/org.eclipse.jdt.core.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..e71285a
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=11
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/Collections.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/Collections.java
new file mode 100644
index 0000000..32b2b20
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/Collections.java
@@ -0,0 +1,126 @@
+import java.util.Deque;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+
+// Represents a mutable collection of items
+interface ICollection {
+ // Is this collection empty?
+ boolean isEmpty();
+ // EFFECT: adds the item to the collection
+ void add(T item);
+ // Returns the first item of the collection
+ // EFFECT: removes that first item
+ T remove();
+}
+
+// first in first out
+class Stack implements ICollection {
+ Deque contents;
+ Stack() {
+ this.contents = new ArrayDeque();
+ }
+ public boolean isEmpty() {
+ return this.contents.isEmpty();
+ }
+ public T remove() {
+ return this.contents.removeLast();
+ }
+ public void add(T item) {
+ this.contents.addFirst(item);
+ }
+}
+
+// last in last out
+class Queue implements ICollection {
+ Deque contents;
+ Queue() {
+ this.contents = new ArrayDeque();
+ }
+ public boolean isEmpty() {
+ return this.contents.isEmpty();
+ }
+ public T remove() {
+ return this.contents.removeLast();
+ }
+ public void add(T item) {
+ this.contents.addLast(item); // NOTE: Different from Stack!
+ }
+}
+
+// highest priority out
+class PriorityQueue implements ICollection {
+ ArrayList heap;
+ IComparator comp;
+ PriorityQueue(ArrayList inputList, IComparator comp) {
+ this.comp = comp;
+ buildHeap(inputList);
+ }
+ PriorityQueue(IComparator comp) {
+ this(new ArrayList(), comp);
+ }
+ void buildHeap(ArrayList inputList) {
+ this.heap = inputList;
+ for (int i = inputList.size() - 1; i >= 0; i--) {
+ this.downHeap(i);
+ }
+ }
+ // swaps the parent and child items
+ void swap(int parentIndex, int childIndex) {
+ T temp = heap.get(parentIndex);
+ heap.set(parentIndex, heap.get(childIndex));
+ heap.set(childIndex, temp);
+ }
+ // recursively uses comp to compare child with parent
+ // and swaps if child is higher priority
+ void upHeap(int childIndex) {
+ int parentIndex = (childIndex - 1) / 2;
+ // comp will return >0 if left has higher priority than right
+ // ergo swap when comp returns <0
+ if (comp.compare(heap.get(parentIndex), heap.get(childIndex)) < 0) {
+ this.swap(parentIndex, childIndex);
+ this.upHeap(parentIndex);
+ }
+ }
+ // recursively uses comp to compare parent with children
+ // and swaps if child is higher priority
+ void downHeap(int parentIndex) {
+ this.downHeapMaxDepth(parentIndex, this.heap.size());
+ }
+ void downHeapMaxDepth(int parentIndex, int maxDepthIndex) {
+ int leftChildIndex = 2 * parentIndex + 1;
+ int rightChildIndex = 2 * parentIndex + 2;
+ if (rightChildIndex < maxDepthIndex) {
+ if (comp.compare(heap.get(leftChildIndex), heap.get(rightChildIndex)) > 0) {
+ if (comp.compare(heap.get(parentIndex), heap.get(leftChildIndex)) < 0) {
+ this.swap(parentIndex, leftChildIndex);
+ this.downHeapMaxDepth(leftChildIndex, maxDepthIndex);
+ }
+ } else if (comp.compare(heap.get(parentIndex), heap.get(rightChildIndex)) < 0) {
+ this.swap(parentIndex, rightChildIndex);
+ this.downHeapMaxDepth(rightChildIndex, maxDepthIndex);
+ }
+ } else if (leftChildIndex < maxDepthIndex) {
+ if (comp.compare(heap.get(parentIndex), heap.get(leftChildIndex)) < 0) {
+ this.swap(parentIndex, leftChildIndex);
+ this.downHeapMaxDepth(leftChildIndex, maxDepthIndex);
+ }
+ }
+ }
+
+ // Interface methods
+ public boolean isEmpty() {
+ return this.heap.isEmpty();
+ }
+ public void add(T item) {
+ this.heap.add(item);
+ this.upHeap(heap.size() - 1);
+ }
+ public T remove() {
+ int lastIndex = this.heap.size() - 1;
+ this.swap(0, lastIndex);
+ T response = this.heap.remove(lastIndex);
+ this.downHeap(0);
+ return response;
+ }
+
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/Comparator.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/Comparator.java
new file mode 100644
index 0000000..773243e
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/Comparator.java
@@ -0,0 +1,44 @@
+interface IPred {
+ boolean apply(T t);
+}
+
+interface IFunc {
+ R apply(A arg);
+}
+
+interface IFunc2 {
+ R apply(A1 arg1, A2 arg2);
+}
+
+interface IComparator {
+ // Returns a negative number if t1 priority is less than t2 priority==-
+ int compare(T t1, T t2);
+}
+
+class ParentLargerInteger implements IComparator {
+ // returns true (>0) if left has higher priority (larger int)
+ public int compare(Integer left, Integer right) {
+ return left - right;
+ }
+}
+
+class ParentSmallerInteger implements IComparator {
+ // returns true (>0) if left has a higher priority (smaller int)
+ public int compare(Integer left, Integer right) {
+ return right - left;
+ }
+}
+
+class ParentLargerEdge implements IComparator {
+ // returns true (>0) if left edge has a higher priority (lower weight)
+ public int compare(Edge left, Edge right) {
+ return left.weight - right.weight;
+ }
+}
+
+class ParentSmallerEdge implements IComparator {
+ // returns true (>0) if left edge has a higher priority (higher weight)
+ public int compare(Edge left, Edge right) {
+ return right.weight - left.weight;
+ }
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/PQExamples.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/PQExamples.java
new file mode 100644
index 0000000..bda801f
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/PQExamples.java
@@ -0,0 +1,142 @@
+import java.util.ArrayList;
+import java.util.Arrays;
+import tester.Tester;
+
+class PQExamples {
+ ArrayList unsortedList;
+ ArrayList upHeapedList;
+ ArrayList downHeapedList;
+ ArrayList sortedList;
+ ArrayList worstCaseList;
+
+ PriorityQueue heapEmptyParentSmaller;
+ PriorityQueue heapPopulatedParentSmaller;
+ PriorityQueue heapGreaterTop;
+
+ IComparator compParentGreater;
+ IComparator compParentSmaller;
+
+ void init() {
+ unsortedList = new ArrayList(
+ Arrays.asList(10, 60, 15, 30, 50, 40, 20, 80, 20, 50));
+ downHeapedList = new ArrayList(
+ Arrays.asList(10, 20, 15, 30, 50, 40, 20, 80, 60, 50));
+ upHeapedList = new ArrayList(
+ Arrays.asList(80, 60, 40, 50, 50, 15, 20, 10, 20, 30));
+ worstCaseList = new ArrayList(
+ Arrays.asList(9, 8, 7, 6, 5, 4, 3, 2, 1));
+
+ compParentGreater = new ParentLargerInteger();
+ compParentSmaller = new ParentSmallerInteger();
+ heapEmptyParentSmaller = new PriorityQueue(compParentSmaller);
+ heapPopulatedParentSmaller = new PriorityQueue(unsortedList, compParentSmaller);
+ }
+ void testSwap(Tester t) {
+ init();
+ t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 0);
+ heapEmptyParentSmaller.heap.add(10);
+ heapEmptyParentSmaller.heap.add(20);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 2);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 10);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 20);
+ heapEmptyParentSmaller.swap(0, 1);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 2);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 20);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 10);
+ }
+ void testUpHeap(Tester t) {
+ init();
+ t.checkExpect(heapEmptyParentSmaller.heap.size(), 0);
+ heapEmptyParentSmaller.heap.add(20);
+ heapEmptyParentSmaller.upHeap(0);
+ t.checkExpect(heapEmptyParentSmaller.heap.size(), 1);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(0), 20);
+ heapEmptyParentSmaller.heap.add(10);
+ heapEmptyParentSmaller.upHeap(1);
+ t.checkExpect(heapEmptyParentSmaller.heap.size(), 2);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(0), 10);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(1), 20);
+ heapEmptyParentSmaller.heap.add(30);
+ heapEmptyParentSmaller.upHeap(2);
+ t.checkExpect(heapEmptyParentSmaller.heap.size(), 3);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(0), 10);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(1), 20);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(2), 30);
+ heapEmptyParentSmaller.heap.add(20);
+ heapEmptyParentSmaller.upHeap(3);
+ t.checkExpect(heapEmptyParentSmaller.heap.size(), 4);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(0), 10);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(1), 20);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(2), 30);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(3), 20);
+ heapEmptyParentSmaller.heap.add(20);
+ heapEmptyParentSmaller.upHeap(4);
+ heapEmptyParentSmaller.heap.add(20);
+ heapEmptyParentSmaller.upHeap(5);
+ t.checkExpect(heapEmptyParentSmaller.heap.size(), 6);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(0), 10);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(1), 20);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(2), 20);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(3), 20);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(4), 20);
+ t.checkExpect(heapEmptyParentSmaller.heap.get(5), 30);
+ }
+ void testDownHeap(Tester t) {
+ init();
+ t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 0);
+ heapEmptyParentSmaller.heap.add(0, 50);
+ heapEmptyParentSmaller.downHeap(0);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.size(), 1);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 50);
+ heapEmptyParentSmaller.heap.add(0, 40);
+ heapEmptyParentSmaller.downHeap(0);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 40);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 50);
+ heapEmptyParentSmaller.heap.add(0, 60);
+ heapEmptyParentSmaller.downHeap(0);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 40);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 60);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(2), 50);
+ heapEmptyParentSmaller.heap.add(0, 30);
+ heapEmptyParentSmaller.downHeap(0);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 30);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 40);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(2), 60);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(3), 50);
+ heapEmptyParentSmaller.heap.add(0, 70);
+ heapEmptyParentSmaller.downHeap(0);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(0), 30);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(1), 50);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(2), 40);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(3), 60);
+ t.checkExpect(this.heapEmptyParentSmaller.heap.get(4), 70);
+ }
+ void testBuildDownHeap(Tester t) {
+ init();
+ heapEmptyParentSmaller.buildHeap(unsortedList);
+ t.checkExpect(heapEmptyParentSmaller.heap, downHeapedList);
+ ArrayList worstDownList = new ArrayList(Arrays.asList(
+ 1, 2, 3, 6, 5, 4, 7, 8, 9));
+ init();
+ heapEmptyParentSmaller.buildHeap(worstCaseList);
+ t.checkExpect(this.heapEmptyParentSmaller.heap, worstDownList);
+ }
+ void testAdd(Tester t) {
+ init();
+ ArrayList addedList_90 = new ArrayList(
+ Arrays.asList(10, 20, 15, 30, 50, 40, 20, 80, 60, 50, 90));
+ ArrayList addedList_9005 = new ArrayList(
+ Arrays.asList(5, 20, 10, 30, 50, 15, 20, 80, 60, 50, 90, 40));
+ this.heapPopulatedParentSmaller.add(90);
+ t.checkExpect(this.heapPopulatedParentSmaller.heap, addedList_90);
+ this.heapPopulatedParentSmaller.add(5);
+ t.checkExpect(this.heapPopulatedParentSmaller.heap, addedList_9005);
+ }
+ void testRemove(Tester t) {
+ init();
+ t.checkExpect(this.heapPopulatedParentSmaller.remove(), 10);
+ ArrayList removedList = new ArrayList(
+ Arrays.asList(15, 20, 20, 30, 50, 40, 50, 80, 60));
+ t.checkExpect(this.heapPopulatedParentSmaller.heap, removedList);
+ }
+}
diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/SpanningTrees.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/SpanningTrees.java
new file mode 100644
index 0000000..940db97
--- /dev/null
+++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect32_SpanningTrees/src/SpanningTrees.java
@@ -0,0 +1,160 @@
+import java.util.ArrayList;
+import java.util.HashMap;
+
+class Util {
+ Util() {}
+
+ boolean isOneTree(ArrayList vertices, HashMap setMap) {
+ // this seems wildly inefficient but it works
+ for (Vertex v0 : vertices) {
+ for (Vertex v1 : vertices) {
+ if (!this.sameTree(v0.name, v1.name, setMap)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ boolean sameTree(String k1, String k2, HashMap setMap) {
+ return this.getStump(k1, setMap).equals(this.getStump(k2, setMap));
+ // if (setMap.get(k1).equals(setMap.get(k2))) {
+ // // easy answer
+ // return true;
+ // } else if (setMap.get(k1).equals(k1) &&
+ // setMap.get(k2).equals(k2)) {
+ // // if both nodes are part of their own sets they cannot be part
+ // // of the same set
+ // return false;
+ // } else {
+ // // run up the tree to see if it ends in the same tree
+ // // i can climb both sides here because when we get to a stump
+ // // the self reference will by definition create a loop that will
+ // // be broken by conditional above
+ // return sameTree(setMap.get(k1), setMap.get(k2), setMap);
+ // }
+ }
+ String getStump(String nodeName, HashMap setMap) {
+ String nodeSet = setMap.get(nodeName);
+ if (nodeName.equals(nodeSet)) {
+ return nodeSet;
+ } else {
+ return getStump(nodeSet, setMap);
+ }
+ }
+ void union(HashMap setMap, String k1, String k2) {
+ if (setMap.get(k2).equals(k2)) {
+ // if k2 is stump of tree change to k1
+ setMap.put(k2, this.getStump(k1, setMap));
+ } else {
+ // go up the tree to change stump's set to k1
+ this.union(setMap, k1, setMap.get(k2));
+ }
+ }
+}
+
+class Vertex {
+ String name;
+ ArrayList outEdges;
+ Vertex(String name, ArrayList outEdges) {
+ this.name = name;
+ this.outEdges = outEdges;
+ }
+ Vertex(String name) {
+ this(name, new ArrayList());
+ }
+ void addEdge(Edge e) {
+ this.outEdges.add(e);
+ }
+}
+
+class Edge {
+ String name;
+ Vertex from, to;
+ int weight;
+ Edge(String name, Vertex from, Vertex to, int weight) {
+ this.name = name;
+ this.from = from;
+ this.to = to;
+ this.weight = weight;
+ to.addEdge(this);
+ from.addEdge(this);
+ }
+ Edge(Vertex from, Vertex to, int weight) {
+ this("", from, to, weight);
+ }
+ Edge(Vertex from, Vertex to) {
+ this("", from, to, 0);
+ }
+}
+
+class Graph {
+ ArrayList vertices;
+ Graph(ArrayList vertices) {
+ this.vertices = vertices;
+ }
+
+ ArrayList makePrimTree() {
+ // The final resulting tree
+ ArrayList tree = new ArrayList();
+ // The set of connected vertices
+ HashMap