Standard Library Sets - Lecture Notes - Data Structures | CSCI 1200, Study notes of Data Structures and Algorithms

Material Type: Notes; Class: DATA STRUCTURES; Subject: Computer Science; University: Rensselaer Polytechnic Institute; Term: Fall 2008;

Typology: Study notes

Pre 2010

Uploaded on 08/09/2009

koofers-user-r2s
koofers-user-r2s 🇺🇸

10 documents

1 / 6

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CSCI-1200 Computer Science II Fall 2008
Lecture 16 Trees, Part I
Review from Lectures 15
Maps containing more complicated values.
Example: index mapping words to the text line numbers on which they appear.
Maps whose keys are class objects.
Example: maintaining student records.
Summary discussion of when to use maps.
Today’s Lecture
STL set container class (like STL map without the pairs)
Binary Trees and Binary Search Trees
Definition & basic operations
Implementation of cs2set class using binary search trees
Note: Lots more tree stuff in CSCI 2300 Data Structures & Algorithms (DSA)!
16.1 Standard Library Sets
STL sets are ordered containers storing unique “keys”. An ordering relation on the keys, which defaults to
operator<, is necessary. Because STL sets are ordered, they are technically not traditional mathematical sets.
Sets are like maps except they have only keys, there are no associated values. Like maps, the keys are constant.
This means you can’t change a key while it is in the set. You must remove it, change it, and then reinsert it.
Access to items in sets is extremely fast! O(log n), just like maps.
Like other containers, sets have the usual constructors as well as the size member function.
16.2 Set iterators
Set iterators, similar to map iterators, are bidirectional: they allow you to step forward (++) and backward
(--) through the set. Sets provide begin() and end() iterators to delimit the bounds of the set.
Set iterators refer to const keys (as opposed to the pairs referred to by map iterators). For example, the
following code outputs all strings in the set words:
for (set<string>::iterator p = words.begin(); p!= words.end(); ++p)
cout << *p << endl;
16.3 Set insert,erase, and find
There are two different versions of the insert member function. The first version inserts the entry into the
set and returns a pair. The first component of the returned pair refers to the location in the set containing the
entry. The second component is true if the entry wasn’t already in the set and therefore was inserted. It is
false otherwise. The second version also inserts the key if it is not already there. The iterator pos is a “hint”
as to where to put it. This makes the insert faster if the hint is good.
pair<iterator,bool> set<Key>::insert(const Key& entry);
iterator set<Key>::insert(iterator pos, const Key& entry);
There are three versions of erase. The first erase returns the number of entries removed (either 0 or 1). The
second and third erase functions are just like the corresponding erase functions for maps. Note that the erase
functions do not return iterators. This is different from the vector and list erase functions.
size_type set<Key>::erase(const Key& x);
void set<Key>::erase(iterator p);
void set<Key>::erase(iterator first, iterator last);
The find function returns the end iterator if the key is not in the set:
const_iterator set<Key>::find(const Key& x) const;
pf3
pf4
pf5

Partial preview of the text

Download Standard Library Sets - Lecture Notes - Data Structures | CSCI 1200 and more Study notes Data Structures and Algorithms in PDF only on Docsity!

CSCI-1200 Computer Science II — Fall 2008

Lecture 16 – Trees, Part I

Review from Lectures 15

  • Maps containing more complicated values. Example: index mapping words to the text line numbers on which they appear.
  • Maps whose keys are class objects. Example: maintaining student records.
  • Summary discussion of when to use maps.

Today’s Lecture

  • STL set container class (like STL map without the pairs)
  • Binary Trees and Binary Search Trees
  • Definition & basic operations
  • Implementation of cs2set class using binary search trees
  • Note: Lots more tree stuff in CSCI 2300 Data Structures & Algorithms (DSA)!

16.1 Standard Library Sets

  • STL sets are ordered containers storing unique “keys”. An ordering relation on the keys, which defaults to operator<, is necessary. Because STL sets are ordered, they are technically not traditional mathematical sets.
  • Sets are like maps except they have only keys, there are no associated values. Like maps, the keys are constant. This means you can’t change a key while it is in the set. You must remove it, change it, and then reinsert it.
  • Access to items in sets is extremely fast! O(log n), just like maps.
  • Like other containers, sets have the usual constructors as well as the size member function.

16.2 Set iterators

  • Set iterators, similar to map iterators, are bidirectional: they allow you to step forward (++) and backward (--) through the set. Sets provide begin() and end() iterators to delimit the bounds of the set.
  • Set iterators refer to const keys (as opposed to the pairs referred to by map iterators). For example, the following code outputs all strings in the set words:

for (set::iterator p = words.begin(); p!= words.end(); ++p) cout << *p << endl;

16.3 Set insert, erase, and find

  • There are two different versions of the insert member function. The first version inserts the entry into the set and returns a pair. The first component of the returned pair refers to the location in the set containing the entry. The second component is true if the entry wasn’t already in the set and therefore was inserted. It is false otherwise. The second version also inserts the key if it is not already there. The iterator pos is a “hint” as to where to put it. This makes the insert faster if the hint is good. pair<iterator,bool> set::insert(const Key& entry); iterator set::insert(iterator pos, const Key& entry);
  • There are three versions of erase. The first erase returns the number of entries removed (either 0 or 1). The second and third erase functions are just like the corresponding erase functions for maps. Note that the erase functions do not return iterators. This is different from the vector and list erase functions. size_type set::erase(const Key& x); void set::erase(iterator p); void set::erase(iterator first, iterator last);
  • The find function returns the end iterator if the key is not in the set: const_iterator set::find(const Key& x) const;

16.4 Overview: Lists vs. Trees vs. Graphs

  • Trees create a hierarchical organization of data, rather than the linear organization in linked lists (and arrays and vectors).
  • Binary search trees are the mechanism underlying maps & sets (and multimaps & multisets).
  • Mathematically speaking: A graph is a set of vertices connected by edges. And a tree is a special graph that has no cycles. The edges that connect nodes in trees and graphs may be directed or undirected.

16.5 Definition: Binary Trees

  • A binary tree (strictly speaking, a “rooted binary tree”) is either empty or is a node that has point- ers to two binary trees.
  • Here’s a picture of a binary tree storing integer values. In this figure, each large box indicates a tree node, with the top rectangle representing the value stored and the two lower boxes representing pointers. Pointers that are null are shown with a slash through the box.
  • The topmost node in the tree is called the root.
  • The pointers from each node are called left and right. The nodes they point to are referred to as that node’s (left and right) children.
  • The (sub)trees pointed to by the left and right pointers at any node are called the left subtree and right subtree of that node.
  • A node where both children pointers are null is called a leaf node.
  • A node’s parent is the unique node that points to it. Only the root has no parent.

16.6 Definition: Binary Search Trees

  • A binary search tree is a binary tree where at each node of the tree, the value stored at the node is - greater than or equal to all values stored in the left subtree, and - less than or equal to all values stored in the right subtree.
  • Here is a picture of a binary search tree stor- ing string values.

ant zebra

cat

dog

goat

horse

lion

mouse

mule

tiger

16.7 Definition: Balanced Trees

  • The number of nodes on each subtree of each node in a “balanced” tree is approximately the same. In order to be an exactly balanced binary tree, what must be true about the number of nodes in the tree?
  • In order to claim the performance advantages of trees, we must assume and ensure that our data structure remains approximately balanced. (You’ll see much more of this in DSA!)

16.11 Exercises

  1. Write a templated function to find the smallest value stored in a binary search tree whose root node is pointed to by p.
  2. Write a function to count the number of odd numbers stored in a binary tree (not necessarily a binary search tree) of integers. The function should accept a TreeNode pointer as its sole argument and return an integer. Hint: think recursively!

16.12 cs2set and Binary Search Tree Implementation

  • A partial implementation of a set using a binary search tree is in the code attached. We will continue to study this implementation in the next lecture & lab.
  • The increment and decrement operations for iterators have been omitted from this implementation. Next lecture we will discuss a couple strategies for adding these operations.
  • We will use this as the basis both for understanding an initial selection of tree algorithms and for thinking about how standard library sets really work.

16.13 cs2set: Class Overview

  • There is an auxiliary TreeNode class, and a tree_iterator class. The classes are templated.
  • The only member variables of the cs2set class are the root and the size (number of tree nodes).
  • The iterator class is declared internally, and is effectively a wrapper on the TreeNode pointers.
    • Note that operator* returns a const reference because the keys can’t change.
    • As just discussed the increment and decrement operators are missing.
  • The main public member functions just call a private (and often recursive) member function (passing the root node) that does all of the work.
  • Because the class stores and manages dynamically allocated memory, a copy constructor, operator=, and destructor must be provided.

16.14 Exercises

  1. Provide the implementation of the member function cs2set::begin. This is essentially the problem of finding the node in the tree that stores the smallest value.
  2. Write a recursive version of the function find.

// Partial implementation of binary-tree based set class similar to std::set. // The iterator increment & decrement operations have been omitted. #ifndef cs2set_h_ #define cs2set_h_ #include #include

// ------------------------------------------------------------------- // TREE NODE CLASS template class TreeNode { public: TreeNode() : left(NULL), right(NULL) {} TreeNode(const T& init) : value(init), left(NULL), right(NULL) {} T value; TreeNode* left; TreeNode* right; };

template class cs2set;

// ------------------------------------------------------------------- // TREE NODE ITERATOR CLASS template class tree_iterator { public: tree_iterator() : ptr_(NULL) {} tree_iterator(TreeNode* p) : ptr_(p) {} tree_iterator(const tree_iterator& old) : ptr_(old.ptr_) {} ~tree_iterator() {} tree_iterator& operator=(const tree_iterator& old) { ptr_ = old.ptr_; return this; } // operator gives constant access to the value at the pointer const T& operator*() const { return ptr_->value; } // comparions operators are straightforward friend bool operator==(const tree_iterator& l, const tree_iterator& r) { return l.ptr_ == r.ptr_; } friend bool operator!=(const tree_iterator& l, const tree_iterator& r) { return l.ptr_ != r.ptr_; } // increment & decrement will be discussed in Lecture 17 and Lab 11

private: // representation TreeNode* ptr_; };

// ------------------------------------------------------------------- // CS2 SET CLASS template class cs2set { public: cs2set() : root_(NULL), size_(0) {} cs2set(const cs2set& old) : size_(old.size_) { root_ = this->copy_tree(old.root_); } ~cs2set() { this->destroy_tree(root_); root_ = NULL; } cs2set& operator=(const cs2set& old) { if (&old != this) { this->destroy_tree(root_); root_ = this->copy_tree(old.root_); size_ = old.size_; } return *this; }

typedef tree_iterator iterator;

int size() const { return size_; } bool operator==(const cs2set& old) const { return (old.root_ == this->root_); }