Link

Sets, Maps, and BSTs

Complete the Reading Quiz by 3:00pm before lecture.

Table of contents

  1. ADTs and Java Collections
  2. Binary Search Trees
  3. Binary Search Trees and the Map ADT

In the very first lecture, we introduced the idea of an abstract data type.

A variable’s data type (or simply “type”) determines its possible values and operations; extending this idea, an abstract data type (ADT) is a data type that does not specify any one implementation. Data structures, such as resizable arrays or linked nodes, implement ADTs.

For example, a List (java.util.List<E>) is a collection storing an ordered sequence of elements, but does not specify how that collection is structured. The following methods are part of Java’s List interface:

add(int index, E element)
Elements can be added to the front, back, or any index in the list.
get(int index)
Each element is accessible by a zero-based index.
remove(Object o)
Optionally, elements can be removed from the list.

ADTs and Java Collections

In Java, both abstract data types and their data structure implementations are provided by the Java Collections Framework. This framework includes familiar interfaces (ADTs) like List as well as concrete classes like ArrayList and LinkedList (data structures). Two other commonly used interfaces are the Set and Map interfaces, which represent the two new ADTs that we’ll be learning in class.

A Set (java.util.Set<E>) is an unordered collection of unique elements. The following methods are part of Java’s Set interface:

add(E element)
Elements can be added to the set.
contains(Object o)
Elements can be checked to see if they are contained in the set.
remove(Object o)
Optionally, elements can be removed from the set.

A Map (java.util.Map<K, V>) is also an unordered collection, but of key-value pairs. Unlike a Set, however, only the key is unique; neither the corresponding value nor the key-value pair is necessarily unique. The following analogous methods are part of Java’s Map interface:

put(K key, V value)
A key-value pair can be added to the map.
containsKey(Object key)
Keys can be checked to see if they are contained in the map.
get(Object key)
The value field in each key-value pair is accessible given its corresponding key.
remove(Object key)
Optionally, elements can be removed from the map.

A note on terminology: a key is a unique identifier used to access items in a data structure, such as the Map ADT. Thus, the elements added to a Set can also be considered keys. Depending on the context, “keys” can be used interchangeably with “item” or “element”.

Binary Search Trees

A tree is a node-based data structure. Like linked nodes, trees are a recursive data structure: each parent node has references to any number of child nodes. We use very particular terminology to discuss trees.

A binary tree is a tree where each node is restricted to only 0, 1, or 2 children, addressed as either the left or the right child relative to the parent node.

A binary search tree is a binary tree with the added binary search invariant (also known as the binary search property): all children to the left of a node contain smaller values and all children to the right of a node contain larger values.

We have some specific vocabulary when discussing tree structures.

Tree Terminology

The labels on the right side are non-recursive; that is, they simply describe the components of the tree. The labels on the left side are recursive; they define the structure of tree in terms of larger or smaller trees. We use these recursive terms because it helps us understand the structure of the tree, and how each part relates to others.

Non-recursive terms: node and value
Each node contains a value. A parent node is joined with an edge to each child node.
Recursive terms: root, subtree, and leaf
Each subtree is itself a valid tree. A tree with zero subtrees is a leaf. A node with no parent within the current (sub)tree is a root.
Using the binary search tree vocabulary described above, think about what fields a Java `BSTNode` class might contain. What did you come up with?

Here’s an idea:

class BSTNode<Value> {
    Value v;
    BSTNode left;
    BSTNode right;
}


Binary Search Trees and the Map ADT

Now, let’s try to connect the Map ADT with the idea of binary search trees. Recall that maps contain key-value pairs, but are ordered only by the key.

Let's modify our `BSTNode` to store key-value pairs.

We can add another field representing the key. Now, we can sort our BST based on keys instead of values!

class BSTNode<Key, Value> {
    Key k;
    Value v;
    BSTNode left;
    BSTNode right;
}



Reading Quiz