Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Hello, I'm using Java on Netbeans. I need help with this practice lab implementation to check if my code is correct and what tweaks need

Hello, I'm using Java on Netbeans. I need help with this practice lab implementation to check if my code is correct and what tweaks need to be make. I'm not well established with writing recursive function in java because I'm used to python so seeing it's implementation helps me learn and I can't find any good tutorial videos that I've found helpful when it comes to applying it to these questions. This is also useful to help me study later on looking back at material. I included all the parts because they are all connected and some are contingent on others. Any help would be greatly appreciated. Thank you very much

Part 1: Insert nodes into a tree

We provided a file BinaryTree.java that defines a class for a binary tree and some methods.

The method insertNode() inserts a node in the leftmost available free spot. That is, if the method is called in the following sequence:

insertNode(50), insertNode(2), insertNode(34), insertNode(19), insertNode(6), then the tree will look like:

image text in transcribed

And, if we call insertNode(22), the tree will look like:

image text in transcribed

Notice that the breadth-first traversal order of the resulting tree is the order in which nodes were inserted.

Implement this method using the fields in the constructor. Notice that there is a LinkedList called nodesThatNeedChildren. This List should contain the TreeNodes who are missing 1 or 2 children. Your insert method will use nodesThatNeedChildren to know which TreeNode to add a child to. For example, in the first tree above, nodesThatNeedChildren =

[TreeNode(34),TreeNode(19),TreeNode(6)] and in the second tree, nodesThatNeedChildren = [TreeNode(34),TreeNode(19),TreeNode(6),TreeNode(22)].

When finished, testInsertionAndtoArray test should pass.

Sanity Check:

Does testInsertionAndtoArray pass?

In the test file, call bt.displayTree() to print out the tree as text. Does this tree look like the example above?

Part 2: reduceAtDepth

Write a method that returns the reduced value of the nodes at a given depth. Here, "reduced" starts with

ReduceFunction.initialValue() and combine each element to the total value using

ReduceFunction.combine(). The depth is given as a parameter. If the depth of the tree is actually less than the given height, then return ReduceFunction.initialValue().

Your method must have a running time in O(N), where N is the number of nodes in the tree.

In BinaryTree.java, complete reduceAtDepth() and reduceAtDepthRecurisve(). reduceAtDepthRecurisve() must use recursion and reduceAtDepth() must be iterative (use a loop).

Notice that the generic data types of reduceAtDepthRecurisve() makes the input and output type to be the same type, T. This is just to make the recursion easier.

Notice that there is a signature for a private helper method reduceAtDepthHelper. It has more arguments to facilitate the recursive calls.

Example

If the tree looks like

image text in transcribed

And the given ReduceFunction is plus (+), then reduceAtDepth(0) is 50, reduceAtDepth(1) is 36 and reduceAtDepth(2) is 25.

Testing

There is one test, sumOfDepthTest, in BinaryTreeTest.java. You must write additional test cases to ensure your code is correct. Your methods will be graded on several additional hidden tests. Some examples of things to test, an empty tree, a tree with only one node, different tree shapes etc.

HINT 1: The provided tests include only one ReduceFunction implementation, IntegerSum. The hidden tests will use other ReduceFunctions, so test your code with other ReduceFunctions that you define.

HINT 2: The provided tests include only BinaryTree. The hidden tests will use other types for BinaryTree, so test your code with other types, such as BinaryTree.

To write a new test case, we recommend that you copy/paste an existing one and change the name of the test method. Then draw your test tree on paper so you know what order to insert nodes using insertNode and what your assertions' expected values are.

Part 3: Queries that use reduceAtDepth

In the queries folder of the project, there is a file named FamilyRecordQuery.java. We created few methods that parses the CSV file of family data and creates a binary tree of the data. Open the CSV file in Excel or in a Text Editor to get a feel for the data. Notice that each level of the tree is a generation of the family. At depth 0 is the child Robert, depth 1 is the parents of Robert, and depth 2 the grandparents and so forth.

Write a method that returns a concatenated string of all the names in a generation separated by one space.

For example, Generation 2: Ryan Jisoon. There is starter code labeled as PART 3. The code queries the treeOfNames by using your ReduceAtDepthRecursive to concatenate names at that depth. For this query, please fix the ConcatenateNames class in FamilyRecordQuery.java.

We've provided the same query below it for the treeOfRecords. It uses your reduceAtDepth to concatenate names of records at that depth. All you need to do is fix the class ConcatenateNamesFromRecord within FamilyRecordQuery.java.

To check your work, use treeOfNames.displayTree() in the main method of FamilyRecordQuery.java and see if the names you printed are correct for the given generation.

Part 4: Select

A "select query" finds the elements that are desired and returns them in depth-first pre-order. Write a method to find the nodes with desired values and return them in a list. To determine what data is desired, we'll use the Predicate interface that is used by filter. Write your method iteratively.

Note that your method must run in linear time: O(n). Implement the method selectIterative.

Example

If the tree contains...

image text in transcribed

and our predicate is "is the element even?", then the answer will be the list [50,2,6,34]. That is, the preorder traversal is [50,2,19,6,34] but we remove the integers where "is element even?" is false to get [50,2,6,34].

Testing

BinaryTreeTest.java contains a single test case selectIterativeTest. You must write additional test cases for both selectIterative. Notice that selectRecursive is already completed. You are to write test cases for both selectRecursive and selectIterative to make sure the code really works. Your methods will be graded on several additional hidden tests and on the quality of your tests for both methods.

HINT 3: The provided tests include only one Predicate implementation, IsEven. The hidden tests will use other Predicates, so test your code with other Predicates that you define.

To write a new test case, we recommend that you copy/paste an existing one and change the name of the test method. Then draw your test tree on paper so you know what order to insert nodes using insertNode and what your assertions' expected values are.

Part 5: Queries that use Select

In FamilyRecordQuery.java uncomment the code required for Part 5 in the main method and the classes. As you noticed, the family has a lot of people named Robert and a lot of engineers. Use your selectIterative and selectRecursive to find these people in the family tree.

To find all the Roberts, fix the SelectName class and search for the exact string Robert in the name field of the FamilyRecord. This must use selectIterative.

To find all the Engineers, fix the SelectJob class and search for any text containing Engineer in the job field of the FamilyRecord. This must use selectRecursive. This query will output a list of many engineer types (people born in 1920 couldnt have been Software Engineers).

Feel free to test our different names or jobs with these queries. To check your work, look at the displayed tree or the CVS file to see that the output is correct.

Part 6: One more query

Uncomment the code in the main method of FamilyRecordQuery.java. Write the code that will return and print out all the people in the family tree that are under the age of 50. Follow the same structure of the previous queries. You must use selectIterative or selectRecursive to complete this task. Once again, check the CVS file or the displayed tree to see if your output is correct.

Reference Code:

familyRecord.cvs

Robert 2024 Seattle WA Student
Ryan 1994 Arlington Heights IL Software Engineer
Jisoon 1995 Dubuque IA Pharmacist
Robert 1963 Park Ridge IL Bio Medical Engineer
Angie 1964 Park Ridge IL Teacher
Boge 1963 East Dubque IL Computer Engineer
Jackie 1970 Bloomington IL Teacher
Robert 1930 Chicago IL Mechanical Engineer
Lee 1932 Chicago IL Homemaker
Mathew 1932 Chicago IL Dentist
Sandy 1936 Chicago IL Teacher
David 1938 Cedar Falls IA Farmer
Suki 1942 Orange CA Shop Owner
Michael 1939 Chicago IL Scientist
Amy 1942 Chicago IL Pharmacist
Carl 1915 New York NY Business
Betty 1920 Washington DC Homemaker
John 1921 Cedar Rapids IA Construction
Jane 1928 Chicago IL Homemaker
Peter 1916 Fargo ND Engineer
Stella 1917 Bismark ND Shop Owner
Nick 1917 Holmes OH Factory Worker
Ethal 1924 Ames IA Programmer
Joe 1922 Fort Wane IN Farmer
Mel 1920 Green Bay WI Chef
Mitch 1919 Chicago IL Inventor
Tara 1911 Desplaines IL Homemaker
Ted 1920 Vernon Hills IL Farmer
Tammy 1918 Springfield IL Seamstress
Chris 1926 Normal IL Farmer
Anna 1925 Traverse City MI Unknown

Code: BinaryTree.java

package binaryTree;

import iterators.Predicate;

import iterators.ReduceFunction;

import java.util.*;

public class BinaryTree {

// the root of the tree

private TreeNode root;

// the queue of TreeNodes in the tree that have 0 or 1 children

private final List> nodesThatNeedChildren;

// number of TreeNodes in the tree

public int size;

public BinaryTree() {

root = null;

nodesThatNeedChildren = new LinkedList();

size = 0;

}

/*

Insert the element d into the BinaryTree at the

"next available location" starting with the left

*/

public void insertNode(T d) {

//PART 1 HERE

}

/* Takes a depth n and a ReduceFunction f

and returns the "combined value" of all elements in the tree at depth n,

where depth=0 is the root.

"combined" means the result of starting with f.initialValue

and "concatentation or combination" each element using f.combine

Requirement: must use a loop

Note on Java syntax: The in front of the method introduces a generic

type name OutT for use only by this method. This is helpful when the generic

type doesn't hold much meaning for the whole class but is meaningful for a

single method.

*/

public OutT reduceAtDepth(int depth, ReduceFunction f) {

//PART 2 HERE

return null;

}

/*Takes a depth n and a ReduceFunction f

and returns the "combined value" of all elements in the tree at depth n,

where depth=0 is the root.

"combined" means the result of starting with f.initialValue

and "concatentation or combination" each element using f.combine

NOTE that the "in" generic type and "out" generic type are the same type.

This makes the recurision a easier.

Requirement: must use a recursive.

*/

public T reduceAtDepthRecursive(int n, ReduceFunction f) {

return null;

// replace the above line with the following line, with arguments

// filled in

// return combineValuesHelper(______, ____, ____, _____);

}

private T reduceAtDepthHelper(int depth, TreeNode node, ReduceFunction f, T sum){

//PART 2 HERE

return null;

}

/* Takes a Predicate p and returns the list of all elements

for which p.check is true. The elements must be returned in

"in order" traversal order.

Requirement: must use a loop

*/

public List selectIterative(Predicate p) {

//PART 4

return null;

}

/* Takes a Predicate p and returns the list of all elements

for which p.check is true. The elements must be returned in

"in order" traversal order.

Requirement: must be recursive

*/

/*

Requirement: must be recursive

*/

public List selectRecursive(Predicate p) {

return selectRecursiveHelper(p, root);

}

private List selectRecursiveHelper(Predicate p, TreeNode node){

if(node == null) {

return null;

}

List res = new LinkedList();

if(p.check(node.data)) {

res.add(node.data);

}

if(node.left != null) {

List wantedNodes = (selectRecursiveHelper(p, node.left));

for(int i = 0; i

res.add(wantedNodes.get(i));

}

}

if(node.right != null) {

List wantedNodes = (selectRecursiveHelper(p, node.right));

for(int i = 0; i

res.add(wantedNodes.get(i));

}

}

return res;

}

//////////////// Dont edit after here //////////////////////

public void printTree() {

Object[] nodeArray = this.toArray();

for (int i = 0; i

System.out.println(nodeArray[i]);

}

}

public void displayTree()

{

Stack globalStack = new Stack();

globalStack.push(root);

int emptyLeaf = 32;

boolean isRowEmpty = false;

System.out.println("****..................................................................................................................................****");

while(isRowEmpty==false)

{

Stack localStack = new Stack();

isRowEmpty = true;

for(int j=0; j

System.out.print(" ");

while(globalStack.isEmpty()==false)

{

TreeNode temp = (TreeNode) globalStack.pop();

if(temp != null)

{

System.out.print(temp.data);

localStack.push(temp.left);

localStack.push(temp.right);

if(temp.left != null ||temp.right != null)

isRowEmpty = false;

}

else

{

System.out.print("--");

localStack.push(null);

localStack.push(null);

}

for(int j=0; j

System.out.print(" ");

}

System.out.println();

emptyLeaf /= 2;

while(localStack.isEmpty()==false)

globalStack.push( localStack.pop() );

}

System.out.println("****..................................................................................................................................****");

}

public Object[] toArray() {

Object[] r = new Object[size];

if (root == null) {

return r;

}

// traverse the tree to visit all nodes,

// adding them to r

List frontier = new LinkedList();

frontier.add(root);

int soFar = 0;

while (frontier.size() > 0) {

TreeNode v = (TreeNode) frontier.get(0);

r[soFar] = v.data;

soFar++;

if (v.left != null) {

frontier.add(v.left);

}

if (v.right != null) {

frontier.add(v.right);

}

frontier.remove(0);

}

return r;

}

private static class TreeNode {

public T data;

public TreeNode left;

public TreeNode right;

public TreeNode(T d) {

data = d;

left = null;

right = null;

}

}

}

Code: BinaryTreeTest.java

import iterators.Predicate;

import binaryTree.BinaryTree;

import iterators.ReduceFunction;

import java.util.List;

import org.junit.Test;

import static org.junit.Assert.*;

public class BinaryTreeTest {

public BinaryTreeTest() {

}

@Test

public void testInsertionAndtoArray() {

BinaryTree bt = new BinaryTree();

bt.insertNode(50);

bt.insertNode(2);

bt.insertNode(34);

bt.insertNode(19);

bt.insertNode(6);

bt.insertNode(22);

Object[] actual = bt.toArray();

Object[] expected = {50, 2, 34, 19, 6, 22};

assertArrayEquals(expected, actual);

}

@Test

public void reduceAtDepthTest() {

BinaryTree bt = new BinaryTree();

bt.insertNode(50);

bt.insertNode(2);

bt.insertNode(34);

bt.insertNode(19);

bt.insertNode(6);

bt.insertNode(22);

int sum = bt.reduceAtDepth(2, new IntegerSum());

assertEquals(47, sum);

}

@Test

public void reduceAtDepthTest2() {

BinaryTree bt = new BinaryTree();

bt.insertNode(50);

bt.insertNode(2);

bt.insertNode(34);

bt.insertNode(19);

bt.insertNode(6);

bt.insertNode(22);

int sum = bt.reduceAtDepthRecursive(2, new IntegerSum());

assertEquals(47, sum);

}

@Test

public void selectIterativeTest() {

BinaryTree bt = new BinaryTree();

bt.insertNode(50);

bt.insertNode(2);

bt.insertNode(34);

bt.insertNode(19);

bt.insertNode(6);

bt.insertNode(22);

Integer[] expected = {50,2,6,34,22};

List answers = bt.selectIterative(new IsEven());

assertArrayEquals(expected, answers.toArray());

}

// Example implementation of ReduceFunction used by the given test

private static class IntegerSum implements ReduceFunction {

@Override

public Integer combine(Integer soFar, Integer x) {

return soFar+x;

}

@Override

public Integer initialValue() {

return 0;

}

}

// Example implementation of IsEven used by the given test

private static class IsEven implements Predicate {

@Override

public boolean check(Integer data) {

return data % 2 == 0;

}

}

/* The staff will run your code on several additional JUnit tests of our own.

You must write additional tests below to provide more evidence that your

method implementations are correct.

This test code is part of the assignment, just like the other code.

If you write a new test and it fails, GREAT! That means you are making

progress. Either the test is wrong and you just need to fix it, or it means you found

a bug in your BinaryTree code and now you can go fix it. Don't remove good tests just

because they fail.

*/

// write your new tests below here, using the @Test methods above as an example.

// PART 2: testing

// PART 4: testing

}

Code: FamilyRecordQuery,java

package queries;

import java.util.Iterator; import readers.LineFileReader; import iterators.Apply; import iterators.ApplyFunction; import binaryTree.BinaryTree; import iterators.Predicate; import iterators.ReduceFunction; import java.io.IOException; import java.util.List;

public class FamilyRecordQuery { public static void main(String[] args) throws IOException{ Iterator lines = new LineFileReader("familyrecord.csv"); Iterator recordsGeneric = new Apply(new ParseCSVLine(), lines); Iterator records = new Apply(new ConvertToRecord(), recordsGeneric); BinaryTree treeOfRecords = new BinaryTree(); BinaryTree treeOfNames = new BinaryTree(); while(records.hasNext()){ FamilyRecord record = records.next(); treeOfNames.insertNode(record.name); treeOfRecords.insertNode(record); } treeOfNames.displayTree();

//PART 3 int generationNumberB = 3; String ageGroupB = treeOfNames.reduceAtDepthRecursive(generationNumberB, new ConcatentateNames()); System.out.println("Generation " + generationNumberB + ": " + ageGroupB);

int generationNumberA = 4; String ageGroupA = treeOfRecords.reduceAtDepth(3, new ConcatenateNamesFromRecord()); System.out.println("Generation " + generationNumberA + ": " + ageGroupA);

//END PART 3 //PART 5 // List robertList = treeOfRecords.selectIterative(new SelectName("Robert")); // System.out.println(robertList); // List engineerList = treeOfRecords.selectRecursive(new SelectJob("Engineer")); // System.out.println(engineerList); //END PART 5

//Part 6 // List under50;

// //INSERT CODE HERE

// System.out.println(under50); }

private static class ConcatenateNamesFromRecord implements ReduceFunction{ //PART 3 }

private static class ConcatentateNames implements ReduceFunction{ //PART 3

} //PART 5 START // private static class SelectName implements Predicate{ // } // private static class SelectJob implements Predicate{ // }

//PART 5 END //PART 6 add new class here

//////////////// Dont edit after here ////////////////////// // Converts a CSV record from an Object[] to a FlightRecord private static class ConvertToRecord implements ApplyFunction { @Override public FamilyRecord apply(Object[] r) { return new FamilyRecord((String)r[0], (int)r[1], (String)r[2], (String)r[3], (String)r[4]); } } private static class ParseCSVLine implements ApplyFunction { @Override public Object[] apply(String x) { String[] fields = x.split(","); Object[] r = new Object[fields.length]; for (int i=0; i

private static class FamilyRecord { public final String name; public final int birthYear; public final String city; public final String state; public final String job; private FamilyRecord(String n, int y, String c, String s, String j) { name = n; birthYear = y; city = c; state = s; job = j; } @Override public String toString(){ return "Family record(Name=" + name + ", Birth Year=" + birthYear + ", City=" + city + ", State=" + state + ", Job=" + job + ")"; } }

}

Code: Filter.java

package iterators;

import java.util.Iterator;

// Iterator that uses a Predicate to filter out elements from the input

public class Filter extends FlatApply {

public Filter(Predicate p, Iterator input) {

// you DO NOT need to modify the constructor

super(new FilteringFlatApplyFunction(p), input);

}

// uses a Predicate to decide whether the input element is output or not

private static class FilteringFlatApplyFunction implements FlatApplyFunction {

}

// You DO NOT need to define hasNext() and next(). FlatApply provides them already.

}

Code: ReduceFunction.java

package iterators;

// Interface for classes to define the functions needed for Reduce.

public interface ReduceFunction {

/* Take the accumulated value soFar and combine it with x

to return a new accumulated value

*/

public OutT combine(OutT soFar, InT x);

/* Return the initial accumulated value */

public OutT initialValue();

}

50 34 19 50 34 19

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Visual Basic6 Database Programming

Authors: John W. Fronckowiak, David J. Helda

1st Edition

ISBN: 0764532545, 978-0764532542

More Books

Students also viewed these Databases questions

Question

Explain the problem of altruism.

Answered: 1 week ago