This week we will play with genericity and OO concepts.
This week we will play with genericity and OO concepts.
A binary search tree is a binary tree such that, for a node, all elements in the left sub-tree are smaller than the element at the node, and all elements in the right sub-tree are greater than the element at the node. As such, there are therefore no two elements of a binary search tree that are equal.
A binary search tree is a binary tree such that, for a node, all elements in the left sub-tree are smaller than the element at the node, and all elements in the right sub-tree are greater than the element at the node. Therefore, binary search trees do not contain duplicate elements.
Because we want to build a generic tree structure, we also need the notion of a comparator, or a less-than-or-equal operator (denoted as leq) for two generic elements which satisfies the following properties:
Because we want to build a generic tree structure, we also need the notion of a comparator, or a less-than-or-equal operator (denoted `leq`) for two generic elements which satisfies the following properties:
- Transitivity: `leq(a, b) && leq(b, c) ⇒ leq(a, c)`
- Transitivity: `leq(a, b) && leq(b, c) => leq(a, c)`
- Reflexivity: `leq(a, a)` is `true`.
- Reflexivity: `leq(a, a)` is `true`.
- Anti-symmetry: `leq(a, b) && leq(b, a) ⇒ a == b`
- Anti-symmetry: `leq(a, b) && leq(b, a) => a == b`
- Totality: either `leq(a, b)` or `leq(b, a)` is `true` (or both)
- Totality: either `leq(a, b)` or `leq(b, a)` is `true` (or both)
Note that the above defines a total order.
Note that the above defines a total order.
...
@@ -18,23 +18,22 @@ Here is the structure we will be using for implementing these trees:
...
@@ -18,23 +18,22 @@ Here is the structure we will be using for implementing these trees:
For consistency, all subtrees must contain the same leq parameter.
For consistency, all subtrees must contain the same leq parameter.
Creating an empty binary tree for integers can be then done as follows:
Creating an empty binary tree for integers can be then done as follows:
```scala
```scala
valintLeq=(x:Int,y:Int)=>x<=y
valintLeq:(Int,Int)=>Boolean=(x,y)=>x<=y
valemptyIntTree:Tree[Int]=newEmptyTree(intLeq)
valemptyIntTree:Tree[Int]=newEmptyTree(intLeq)
```
```
## Exercise 0
## Exercise 1
Given only `leq` for comparison, how can you test for equality? How about strictly-less-than?
Given only `leq` for comparison, how can you test for equality? How about strictly-less-than?
## Exercise 1
## Exercise 2
Define the size method on `Tree[T]`, which returns its size, i.e. the number of Nodes in the tree.
Define the size method on `Tree[T]`, which returns its size, i.e. the number of Nodes in the tree.
...
@@ -47,12 +46,12 @@ trait Tree[T] {
...
@@ -47,12 +46,12 @@ trait Tree[T] {
Implement it in two ways:
Implement it in two ways:
- within `Tree[T]`, using pattern matching,
1. within `Tree[T]`, using pattern matching,
- in the subclasses of `Tree[T]`.
2. in the subclasses of `Tree[T]`.
## Exercise 2
## Exercise 3
Define the `add` method, that adds an element to a `Tree[T]`, and returns the resulting tree
Define the `add` method, that adds an element to a `Tree[T]`, and returns the resulting tree:
```scala
```scala
defadd(t:T):Tree[T]=???
defadd(t:T):Tree[T]=???
...
@@ -60,7 +59,7 @@ def add(t: T): Tree[T] = ???
...
@@ -60,7 +59,7 @@ def add(t: T): Tree[T] = ???
Remember that trees do not have duplicate values. If t is already in the tree, the result should be unchanged.
Remember that trees do not have duplicate values. If t is already in the tree, the result should be unchanged.
## Exercise 3
## Exercise 4
Define the function `toList`, which returns the sorted list representation for a tree. For example, `emptyIntTree.add(2).add(1).add(3).toList` should return `List(1, 2, 3)`
Define the function `toList`, which returns the sorted list representation for a tree. For example, `emptyIntTree.add(2).add(1).add(3).toList` should return `List(1, 2, 3)`
...
@@ -70,9 +69,9 @@ def toList: List[T] = ???
...
@@ -70,9 +69,9 @@ def toList: List[T] = ???
You can use the `Nil` operator for creating an empty list, and the `::` operator for adding a new element to the head of a list: `1 :: List(2, 3) == List(1, 2, 3)`. You are naturally free to define any auxiliary functions as necessary.
You can use the `Nil` operator for creating an empty list, and the `::` operator for adding a new element to the head of a list: `1 :: List(2, 3) == List(1, 2, 3)`. You are naturally free to define any auxiliary functions as necessary.
## Exercise 4
## Exercise 5
Define the function `sortedList`, which takes an unsorted list where no two elements are equal, and returns a new list that contains all the elements of the previous list (and only those), but in increasing order.
Define the function `sortedList`, which takes an unsorted list where no two elements are equal, and returns a new list that contains all the elements of the previous list (and only those), in increasing order.