Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binary tree folding

Tags:

tree

scala

fold

I have been given the following definition of a binary tree

abstract class Tree[+A]
case class Leaf[A](value: A) extends Tree[A]
case class Node[A](value: A, left: Tree[A], right: Tree[A]) extends Tree[A]

and the following function

def fold_tree[A,B](f1: A => B)(f2: (A, B, B) => B)(t: Tree[A]): B = t match {
    case Leaf(value) => f1(value)
    case Node(value, l, r) => f2(value, fold_tree(f1)(f2)(l), fold_tree(f1)(f2)(r)) //post order
  }

I have been asked to return the rightmost value in the tree using the fold method. How would this work? I'm not sure I fully understand fold, but I thought the point of fold was to do some operation to every element in the tree. How can I use it to just return the rightmost value of a tree?

I am also unsure as to how to call the method. I keep getting issues with unspecified parameter type. Can someone show me the proper way to call this fold_tree method?

like image 427
Vandexel Avatar asked Sep 27 '16 06:09

Vandexel


People also ask

How do you know if a binary tree is foldable?

Question: Given a binary tree, find out if the tree can be folded or not. A tree can be folded if left and right subtrees of the tree are structure wise mirror image of each other. An empty tree is considered as foldable.

Is there a BST class in Java?

You will learn to Create a BST, Insert, Remove and Search an Element, Traverse & Implement a BST in Java: A Binary search tree (referred to as BST hereafter) is a type of binary tree. It can also be defined as a node-based binary tree. BST is also referred to as 'Ordered Binary Tree'.

Does Java have a tree implementation?

In Java, a tree node is implemented using a class. The data inside every node can be a string, char, integer, double, or float data type. A binary tree can be implemented in two ways: A node representation and an array representation.


1 Answers

How would this work? I'm not sure I fully understand fold

What your foldTree method is doing is recursively walking the tree, applying itself to each Node or Leaf it encounters in the way. The method also has two type parameters that need to be applied, A and B, depending on the type of the provided tree.

Let's for the sake of the example say we have a Tree[Int] defined like this:

val n = Node(1, Leaf(2), Node(3, Leaf(5), Node(4, Leaf(42), Leaf(50))))

The tree has a structure that looks like this:

Tree

We want to get the right most value, which is 50. In order to do that with the current implementation of foldTree, we need to provide it two methods:

  1. f1: A => B: Given an A, project a B value
  2. f2: (A, B, B) => B: Given one A and two B values, project a B.

We can see that f1 is applied over a Leaf, and f2 is applied over a Node (hence the different number of elements provided to each method). So this gives us a hint that the functions we provide to foldTree will be applied to each one, respectively.

Packed with that knowledge, given our tree:

val n = Node(1, Leaf(2), Node(3, Leaf(55), Node(4, Leaf(42), Leaf(50))))

We provide the following method:

println(foldTree[Int, Int](identity)((x, y, z) => z)(n))

What this means is as follows:

  1. If we encounter a Leaf node and map over it (by applying f1 on it), we simply want to extract it's value.
  2. When encountering a Node element (and applying f2 to it), we want to take the right most element, which is projected by the third element z in our method.

Running this, yields the expected result: 50.

If we want to expand this generically for any A, we can say:

def extractRightmostValue[A](tree: Tree[A]) =
  foldTree[A, A](identity)((x, y, z) => z)(tree)
like image 192
Yuval Itzchakov Avatar answered Nov 15 '22 16:11

Yuval Itzchakov