207
C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved Chapter Fourteen: Sets, Maps, and Priority Queues Slides by Evan Gallagher

Chapter14 fix

Embed Size (px)

Citation preview

Page 1: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Chapter Fourteen: Sets, Maps, and Priority Queues

Slides by Evan Gallagher

Page 2: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

• To become familiar with the set, map,and priority queue data types

• To understand the implementation ofbinary search trees and heaps

• To learn about the efficiency of operationson tree structures

Chapter Goals

Page 3: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

SetsIn mathematics

and computer science,an unordered collection of distinct items

is called a set.

Page 4: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

SetsAs with vectors and lists,

you provide the type the set will containwhen you create a set.

#include <set>…

set<Printer> names;

Page 5: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

SetsA set does not allow duplicates andsupports these fundamental operations:

• Adding an element.• Removing an element.• Finding an element.• Traversing all elements.

Page 6: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Sets

#include <set>…

set<string> names;

Page 7: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

SetsYou use the insert member function to add elements:

names.insert("Romeo");names.insert("Juliet"); // nice couple

names.insert("Romeo");// Has no effect:// "Romeo" is already in the set

Page 8: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

SetsYou use the erase member function to remove elements:

names.erase("Juliet"); // Juliet exits

names.erase("Juliet");// Has no effect:// "Juliet" is no longer in the set;

Page 9: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

SetsTo determine whether a value is in the set,

use the count member function.It returns 1 if the value is in the set, 0 otherwise.

set<string> names;names.insert("Romeo");

int c = names.count("Romeo"); // count returns 1if ( c == 1 ) ...

Page 10: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

SetsYou can visit the elements of a set with an iterator:

names.insert("Tom");names.insert("Dick");names.insert("Harry");

set<string>::iterator pos;

for (pos = names.begin(); pos != names.end(); pos++){ cout << *pos << " ";}

The output is:

Dick Harry Romeo Tom

Page 11: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

SetsYou will notice that

these are not in the order they were inserted:

This doesn’t mean that you should consider a “set” as ordered – it just means internally,

C++’s uses an ordering for it’s set type.

Dick Harry Romeo Tom

Page 12: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

MultisetsA multiset

is an unordered containerthat can contain multiple copies of an element.

Page 13: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

MultisetsThe set header file also. has multiset.

#include <set>…multiset<string> names;names.insert("Romeo");names.insert("Juliet");names.insert("Romeo");// Now names.count("Romeo") is 2names.erase("Juliet");// Now names.count("Juliet") is 0names.erase("Juliet");// Has no effect:// "Juliet" is no longer in the bag

Page 14: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

SetsHow would we find misspellt words

(like that one!)?

How about a list of incorrectly spelled words?

Hm…

Page 15: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

SetsHow would we find misspellt words

(like that one!)?

How about a container of correctly spelled words?

We could fill our “dictionary” container,our list,

from a file of correctly spelled words andlook up each word to be checked in it.

Page 16: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

SetsBut, a list?

A list would requiresequential accessfor every lookup.

Not good.

Hm…

Page 17: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

SetsHow about a set of correctly spelled words?

sets allow very fast lookup.

They are not fast at inserting elements,but that would happen only once in this problem

and after filling,most of the work would be

looking to see if a word is in the set.

Page 18: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Sets#void spell_check(istream& dictionary, istream& text){ set<string> words; string word;

// First put all words from the dictionary into the set while (dictionary >> word) { words.insert(word); }

// Then read words from file to be spellchecked while (text >> word) { if (words.count(word) == 0) { cout << "Misspelled word " << word << endl; } }}

Page 19: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

SetsA set implementation is allowed

to rearrange its elements in any way it choosesso that it can find elements quickly.

If a set keeps it’s elements in sorted order,then it could use a binary search,

O(n),top locate elements.

That’s good.

But…

Page 20: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

SetsIf an array were used to store the elements of a set,

insertion and removal would suffer.In an array these actives are slow; an O(n).

Not good.

We need to think…

…ecologically:

Page 21: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search TreesTREES!

Upside down trees!

Page 22: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search TreesYou’ll need to think about a tree’s root

as being at the top,

root

Page 23: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Treesand the rest of the tree below that.

root

Page 24: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Treesand the rest of the tree below that.

root

Page 25: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search TreesIn computer science, a special type of tree,

a binary tree, has similarities to a linked list:

it has pointers to the “next”,but instead of only one “next” pointer,

it has two.

Thus the ‘bi’ in binary.

Page 26: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search TreesThese two “nexts” are usually named:

left and rightand we say that every nodehas at most two “children.”

Again that ‘bi’.

root

left children right children

Page 27: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search TreesEach node has this property

of having at most two descendants.

left children

left children left children right childrenright children

right children

Page 28: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search TreesA special kind of binary tree, called a

binary search tree is used for quick lookup.

Page 29: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search TreesA binary search tree maintains this property:

The data values of all descendants to the left of any nodeare less than the data value stored in that node,

and all descendants to the righthave greater data values.

< <

Page 30: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

This is a binary search tree.

Page 31: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Let’s verify this.

Binary Search Trees

Page 32: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

First, it is a binary tree

– each node has at most twodescendants.

Binary Search Trees

Page 33: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees Now for the required ordering

of the data in the tree.

Page 34: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

Look at the “root” node(yes, the one at the top!),

Page 35: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

Is “Juliet” greater than all the data in that node’s left descendant?

Page 36: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

“Eve”, “Adam” ,“Harry” < “Juliet”?

<

Page 37: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

“Eve”, “Adam” ,“Harry” < “Juliet”?Yes.

<

Page 38: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

What about theright descendants’ data?

<

Page 39: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

< <

“Romeo”, “Tom” < “Juliet”?

Page 40: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

< <

“Romeo”, “Tom” < “Juliet”?Yes.

Page 41: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees Now we must look at the root’s

left descendants.

< <

Page 42: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

“Adam” < “Eve”?

<

< <

Page 43: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

“Adam” < “Eve”?Yes.

<

< <

Page 44: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

And the data to the rightof the node with “Eve”?

< <

<

Page 45: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

Eve”< “Harry”?

<

< <

<

Page 46: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

Eve”< “Harry”?Yes.

<

< <

<

Page 47: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

<

< <

<

We consider the left and rightdescendants of the node with “Adam”.

Page 48: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

There are none.

<

< <

<

Page 49: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

There are none.So “Adam” is in order, obviously.

<

< <

<

Page 50: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

We consider the left and right

descendants of the node with “Harry”.

<

< <

<

Page 51: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

There are none.

<

< <

<

Page 52: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

There are none.“Harry” is in the right place.

<

< <

<

Page 53: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

Now we must look at the root’s

right descendants.

< <

<<

Page 54: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

This node has noleft descendants.

< <

<<

Page 55: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

So “Romeo” is in order.

< <

<<

Page 56: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

Now for the right descendants.

< <

<<

Page 57: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

“Romeo” < “Tom”?

<

<<<

<

Page 58: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

“Romeo” < “Tom”?

Yes.

<

<<<

<

Page 59: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

<

<<<

The node with “Tom”has no descendants,

<

Page 60: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

<

<<<

The node with “Tom”has no descendants,

so “Tom” is fine.

<

Page 61: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

This tree has theBinary Search Tree

properties.

Page 62: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

<

<<<

This tree has theBinary Search Tree

properties.

<

Page 63: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search TreesWe will use classes for our binary search tree:

#class TreeNode{...private: string data; TreeNode* left; TreeNode* right;friend class BinarySearchTree;};class BinarySearchTree{ ...private: TreeNode* root;};

Page 64: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees There is one BinarySearchTree

Page 65: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

There is one BinarySearchTreeAll the data is in the TreeNodes.

Page 66: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search TreesTo insert data into the tree, use the following algorithm:

• If you encounter a non-NULL node, look at its data value. If the data value of that node is larger than the one you want to insert, continue the process with the left child. If the existing data value is smaller, continue the process with the right child.

• If you encounter a NULL node, replace it with the new node.

Page 67: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Using this algorithm, notice the left, right orderingof these your insertions.

BinarySearchTree;tree.insert("Juliet"); 1tree.insert("Tom"); 2tree.insert("Dick"); 3tree.insert("Harry"); 4

Binary Search Trees

Page 68: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

The code for the insert member function of the BinarySearchTree class:

void BinarySearchTree::insert(string data){ TreeNode* new_node = new TreeNode; new_node->data = data; new_node->left = NULL; new_node->right = NULL; if (root == NULL) { root = new_node; } else { root->insert_node(new_node); }}

Binary Search Trees

Page 69: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

When going left, if not NULL, insert_node is called to insert left:

void TreeNode::insert_node(TreeNode* new_node){ if (new_node->data < data) { if (left == NULL) { left = new_node; } else { left->insert_node(new_node); } }

Binary Search Trees

Page 70: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Same process when going right:

else if (data < new_node->data) { if (right == NULL) { right = new_node; } else { right->insert_node(new_node); } }}

Binary Search Trees

Page 71: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Watch as we add “Romeo”.

tree.insert("Romeo"); 5

“Juliet” < “Romeo”insert somewherein the right.

Binary Search Trees

Page 72: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Watch as we add “Romeo”.

tree.insert("Romeo"); 5

“Juliet” < “Romeo”insert somewherein the right.

“Romeo” < “Tom”insert somewherein the left .

Binary Search Trees

Page 73: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Watch as we add “Romeo”.

tree.insert("Romeo"); 5

“Juliet” < “Romeo”insert somewherein the right.

“Romeo” < “Tom”insert somewherein the left .

But the left is Null,so insert new there.

Binary Search Trees

Page 74: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Watch as we add “Romeo”.

tree.insert("Romeo"); 5

“Juliet” < “Romeo”insert somewherein the right.

“Romeo” < “Tom”insert somewherein the left .

But the left is Null,so insert new there.

Binary Search Trees

Page 75: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Note that we still have a binary search tree.

tree.insert("Romeo"); 5

“Juliet” < “Romeo”insert somewherein the right.

“Romeo” < “Tom”insert somewherein the left .

But the left is Null,so insert new there.

Binary Search Trees

Page 76: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Now consider removing an item from a binary search tree.First, find it:

This is the binary search part.

Starting with the root:

if the data to find matches the current node’s data,--- we’ve found it

otherwise, if the data to find is less than the current node’s data,--- continue searching in the left descendants

otherwise, (the data to find is greater),--- continue searching in the right descendants

Binary Search Trees

Page 77: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Once we have found the node to delete,there are three possibilities:

Very Easy

Easy

A Bit More Work

Binary Search Trees

Page 78: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Very Easy

The node to delete has no children,both it’s left and right links are NULL:

set its parent’s link that points to the node to NULL.

Binary Search Trees

Page 79: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Very Easy

The node to delete has no children,both it’s left and right links are NULL:

set its parent’s link that points to the node to NULL.

Binary Search Trees

Page 80: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

EasyThe node to delete has only one child:

Binary Search Trees

Page 81: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

EasyThe node to delete has only one child:

modify the parent link that points to the node so thatit points to the child instead.

Binary Search Trees

Page 82: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

EasyThe node to delete has only one child:

modify the parent link that points to the node so thatit points to the child instead.

Binary Search Trees

Page 83: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

A Bit More Work

Rather than removing the node,it is easier to replace its data value

with the next larger value in the tree.

That replacement preserves the binary search tree property.

Binary Search Trees

Page 84: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

A Bit More Work

To locate the next larger value,go to the right subtree andfind its smallest data value

by following only left child links.

Once you reach a node that has no left child, that’s the smallest data value of the subtree.

Now remove that nodewhich is easy

because it has at most one child.

(But don’t remove it before you deal with the data value!)

Binary Search Trees

Page 85: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

Page 86: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

Page 87: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

Page 88: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

Page 89: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

Page 90: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Analysis time!Binary Search Trees

Page 91: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Like nodes in a list,tree nodes are allocated one at a time.

No existing elements need to be movedwhen a new element is inserted in the tree;

that is an advantage.

Binary Search Trees

Page 92: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

How fast insertion depends on the shape of the tree.

When each node has approximately as many descendantson the left as on the right the tree is called

balanced.then insertion takes O(log (n)) time,

where n is the number of nodes in the tree.

This is a consequence of the fact thatabout half of the nodes are eliminated in each step.

On the other hand, if the tree happens to beunbalanced,

then insertion can be possiblyas slow as insertion into linked list

Binary Search Trees

Page 93: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

Consider the node with “Tom”

– it has three nodes on its left and zero on its right.

Page 94: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

Consider the node with “Tom”

– it has three nodes on its left and zero on its right.

Very unbalanced!

Page 95: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

If new elements are fairly random,the resulting tree is likely to be well balanced.

However,if the incoming elements happen to be

in sorted order already,then the resulting tree is completely unbalanced.

Each new element is inserted at the end,and the entire tree must be traversed

every time to find that end!

Binary Search Trees

Page 96: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

There are more sophisticated tree structureswhose functions keep trees balanced at all times.

In these tree structures,one can guarantee that

finding, adding, and removing elements takesO(log(n)) time.

The standard C++ library usesred-black trees,

a special form of balanced binary trees,to implement sets and maps.

Binary Search Trees

Page 97: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Binary Search Trees

Page 98: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Once data has been inserted into a binary search tree, it turns out to be surprisingly simple to

print all elements in sorted order.

You know that all data in the left subtree of any nodemust come before the node and

before all data in the right subtree.

So to print in sorted order:

Print the left subtree.Print the node’s data.

Print the right subtree.

Tree Traversal

Page 99: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Print the left subtree.That’s the tree whoseroot is the node with “Dick”.

Tree Traversal

Page 100: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Print the left subtree.Print the node’s data.That’s “Juliet”.

Tree Traversal

Page 101: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Print the left subtree.Print the node’s data.Print the right subtree.That’s the tree whoseroot is the node with “Tom”.

Tree Traversal

Page 102: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Print the left subtree.Print the node’s data.Print the right subtree.

Done!

Tree Traversal

Page 103: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

How do you print the subtree starting at the node that has “Dick”?Tree Traversal

Page 104: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Consider that the node that contains “Dick” is a tree – it is!So apply the same algorithm:

Print the left subtree. Print the node’s data.Print the right subtree.

Tree Traversal

Page 105: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Print the left subtree. There is nothing to print.Print “Dick”.Print the right subtree.

Tree Traversal

Page 106: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Print the left subtree. There is nothing to print.Print “Dick”.Print the right subtree. That node with “Harry” has no subtrees but it should still be handled the same way.

Tree Traversal

Page 107: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Print the left subtree. There is nothing to print.Print “Harry”.Print the right subtree There is nothing to print.

Tree Traversal

Page 108: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

That process printedthe left subtree of the node that contains“Juliet”.

Then we printed “Juliet”.

Now we mustprint the rightsubtree.

Tree Traversal

Page 109: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

That process printedthe left subtree of the node that contains“Juliet”.

Then we printed “Juliet”.

Now we mustprint the rightsubtree.

Tree Traversal

Page 110: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

That process printedthe left subtree of the node that contains“Juliet”.

Then we printed “Juliet”.

Now we mustprint the rightsubtree.

Tree Traversal

Page 111: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

That process printedthe left subtree of the node that contains“Juliet”.

Then we printed “Juliet”.

Now we mustprint the rightsubtree.

“Romeo”

Tree Traversal

Page 112: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

That process printedthe left subtree of the node that contains“Juliet”.

Then we printed “Juliet”.

Now we mustprint the rightsubtree.

“Romeo”“Tom”

Tree Traversal

Page 113: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

That process printedthe left subtree of the node that contains“Juliet”.

Then we printed “Juliet”.

Now we mustprint the rightsubtree.

“Romeo”“Tom”Nothing to print.

Tree Traversal

Page 114: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Done!

Tree Traversal

Page 115: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

The code for traversing a tree:

void TreeNode::print_nodes() const{ if (left != NULL) { left->print_nodes(); } cout << data << endl; if (right != NULL) { right->print_nodes(); }}

Tree Traversal

Page 116: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

print_nodes will be used in a call to print the whole tree:

void BinarySearchTree::print() const{ if (root != NULL) { root->print_nodes(); }}

Tree Traversal

Page 117: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

The visitation scheme we usedto print in sorted order is called

inorder traversal.

There are two other traversals:

preorder traversal,

postorder traversal.

Tree Traversal

Page 118: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

inorder traversal:Visit the left subtree.Visit the root.Visit the right subtree.

preorder traversal:Visit the root.Visit the left subtree.Visit the right subtree.

postorder traversal:Visit the left subtree.Visit the right subtree.Visit the root.

Tree Traversal

1st

1st

1st

2nd

2nd

2nd

3rd

3rd

3rd

Page 119: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

The code for all of these activities:

Tree Traversal

Page 120: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

#include <iostream>#include <string>using namespace std;

class TreeNode{public: void insert_node(TreeNode* new_node); void print_nodes() const; bool find(string value) const;private: string data; TreeNode* left; TreeNode* right;friend class BinarySearchTree;};

Tree Traversalch14/bintree.cpp

Page 121: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

class BinarySearchTree{public: BinarySearchTree(); void insert(string data); void erase(string data); int count(string data) const; void print() const;private: TreeNode* root;};

BinarySearchTree::BinarySearchTree(){ root = NULL;}

Tree Traversalch14/bintree.cpp

Page 122: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

void BinarySearchTree::print() const{ if (root != NULL) { root->print_nodes(); }}

Tree Traversalch14/bintree.cpp

Page 123: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

void BinarySearchTree::insert(string data){ TreeNode* new_node = new TreeNode; new_node->data = data; new_node->left = NULL; new_node->right = NULL; if (root == NULL) { root = new_node; } else { root->insert_node(new_node); }}

Tree Traversalch14/bintree.cpp

Page 124: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

void TreeNode::insert_node(TreeNode* new_node){ if (new_node->data < data) { if (left == NULL) { left = new_node; } else { left->insert_node(new_node); } }

Tree Traversalch14/bintree.cpp

Page 125: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

else if (data < new_node->data) { if (right == NULL) { right = new_node; } else { right->insert_node(new_node); } }}

Tree Traversalch14/bintree.cpp

Page 126: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

int BinarySearchTree::count(string data) const{ if (root == NULL) { return 0; } else if (root->find(data)) { return 1; } else { return 0; }}

Tree Traversalch14/bintree.cpp

Page 127: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

void BinarySearchTree::erase(string data){ // Find node to be removed TreeNode* to_be_removed = root; TreeNode* parent = NULL; bool found = false; while (!found && to_be_removed != NULL) { if (to_be_removed->data < data) { parent = to_be_removed; to_be_removed = to_be_removed->right; }

Tree Traversalch14/bintree.cpp

Page 128: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

else if (data < to_be_removed->data) { parent = to_be_removed; to_be_removed = to_be_removed->left; } else found = true; }

if (!found) return;

// to_be_removed contains data

Tree Traversalch14/bintree.cpp

Page 129: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

// If one of the children is empty, // use the other

if (to_be_removed->left == NULL || to_be_removed->right == NULL) { TreeNode* new_child; if (to_be_removed->left == NULL) { new_child = to_be_removed->right; } else { new_child = to_be_removed->left; }

Tree Traversalch14/bintree.cpp

Page 130: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

if (parent == NULL) // Found in root { root = new_child; } else if (parent->left == to_be_removed) { parent->left = new_child; } else { parent->right = new_child; } return; }

Tree Traversalch14/bintree.cpp

Page 131: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

// Neither subtree is empty // Find smallest element of the right subtree

TreeNode* smallest_parent = to_be_removed; TreeNode* smallest = to_be_removed->right; while (smallest->left != NULL) { smallest_parent = smallest; smallest = smallest->left; }

Tree Traversalch14/bintree.cpp

Page 132: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

// smallest contains smallest child // in right subtree

// Move contents, unlink child to_be_removed->data = smallest->data; if (smallest_parent == to_be_removed) { smallest_parent->right = smallest->right; } else { smallest_parent->left = smallest->right; } }

Tree Traversalch14/bintree.cpp

Page 133: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

bool TreeNode::find(string value) const{ if (value < data) { if (left == NULL) { return false; } else { return left->find(value); } }

Tree Traversalch14/bintree.cpp

Page 134: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

else if (data < value) { if (right == NULL) { return false; } else { return right->find(value); } } else { return true; }}

Tree Traversalch14/bintree.cpp

Page 135: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

void TreeNode::print_nodes() const{ if (left != NULL) { left->print_nodes(); } cout << data << endl; if (right != NULL) { right->print_nodes(); }}

Tree Traversalch14/bintree.cpp

Page 136: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

int main(){ BinarySearchTree t; t.insert("D"); t.insert("B"); t.insert("A"); t.insert("C"); t.insert("F"); t.insert("E"); t.insert("I"); t.insert("G"); t.insert("H"); t.insert("J"); t.erase("A"); // Removing leaf t.erase("B"); // Removing element with one child t.erase("F"); // Removing element with two children t.erase("D"); // Removing root t.print(); cout << t.count("E") << endl; cout << t.count("F") << endl; return 0;}

Tree Traversalch14/bintree.cpp

Page 137: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Map

Maps

Page 138: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

In computer science, a map is a data type that keepsassociations between keys and values.

Every key in the map has a unique value,but a value may be associated with several keys.

Maps

Page 139: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Here is a map that associates names with colors.This map might describe the favorite colors of various people.

Maps

Page 140: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

To use the map class in the standard library,you must do the expected #include:

#include <map>

Maps

Page 141: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

When you define your map variable,you must specify the type of the key and the value:

#include <map>

map<string, double> scores;

Maps

Page 142: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

You use the [] operatorto associate keys and values.

#include <map>

map<string, double> scores;

scores["Tom"] = 90;scores["Dick"] = 86;scores["Harry"] = 100;

Maps

Page 143: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

You use the [] operatorto associate keys and values.

#include <map>

map<string, double> scores;

scores["Tom"] = 90;scores["Dick"] = 86;scores["Harry"] = 100;

cout << "Tom’s score: " << scores["Tom"];

Maps

Page 144: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

To find out whether a key is present in the map,use the find member function, which returns

an iterator that points to the entry with the given key,or past the end of the container if the key is not present.

map<string, double>::iterator pos = scores.find("Harry");

Maps

Page 145: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

When you deference an iterator on map<K, V>(key type K and value type V)

you get an element of type

pair<K, V>.

The pair class is a simple class defined in the<utility> header that stores a pair of values.

It has two public (!) data members first and second.

So to get at the value associated with a key:

Maps

Page 146: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

So to get at the value associated with a key:

#include< utility>

map<string, double>::iterator pos = scores.find("Harry");

if (pos == scores.end()) // Check if there was a match{ cout << "No match for Harry";}else{ cout << "Harry’s score: " << pos->second; // pos points to a pair<string, int>}

Maps

Page 147: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

So to get at the value associated with a key:

#include< utility>

map<string, double>::iterator pos = scores.find("Harry");

if (pos == scores.end()) // Check if there was a match{ cout << "No match for Harry";}else{ cout << "Harry’s score: " << pos->second; // pos points to a pair<string, int>}

Maps

Page 148: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Note how we checked for if not found.

#include< utility>

map<string, double>::iterator pos = scores.find("Harry");

if (pos == scores.end()) // Check if there was a match{ cout << "No match for Harry";}else{ cout << "Harry’s score: " << pos->second; // pos points to a pair<string, int>}

Maps

Page 149: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

To iterate over the contents of a map:

#include< utility>

map<string, double>::iterator pos;

for (pos = scores.begin(); pos != scores.end(); pos++){ cout << "The score of " << pos->first << " is " << pos->second << endl;}

Maps

Page 150: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

A multimap is similar to a mapbut it can have multiple valuesassociated with the same key.

Maps

Page 151: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

The map header file also has multimap .

#include <map>

Maps

Page 152: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Instead of using the [] operator,you use the insert and erase methods to insert pairs.

#include <map>#include< utility>

multimap<string, string> friends;

friends.insert(make_pair("Tom", "Dick")); // Dick is a friend of Tomfriends.insert(make_pair("Tom", "Harry")); // Harry is also a friend of Tomfriends.erase(make_pair("Tom", "Dick")); // Dick is no longer a friend of Tom

The make_pair function(also defined in the <utility> header)

makes a pair object from its arguments.

Maps

Page 153: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

A multimap would be good for a telephone database:

#include <iostream>#include <map>#include <utility>#include <string>#include <vector>using namespace std;

/**TelephoneDirectory maintains a map of name/number pairsand an inverse multimap of numbers and names.*/class TelephoneDirectory{public:

Mapsch14/tele.cpp

Page 154: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

/** Adds a new name/number pair to database. @param name the new name @param number the new number */ void add_entry(string name, int number);

/** Finds the number associated with a name. @param name the name being searched @return the associated number, or zero if not found in database */ int find_entry(string name);

/** Finds the names associated with a number. @param number the number being searched @return the associated names */ vector<string> find_entries(int number);

Mapsch14/tele.cpp

Page 155: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

/** Prints all entries. */ void print_all();

private: map<string, int> database; multimap<int, string> inverse_database;};

void TelephoneDirectory::add_entry(string name, int number){ database[name] = number; inverse_database.insert(make_pair(number, name));}

Mapsch14/tele.cpp

Page 156: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

int TelephoneDirectory::find_entry(string name){ map<string, int>::iterator p = database.find(name); if (p == database.end()) { return 0; // Not found } else { return p->second; }}

Mapsch14/tele.cpp

Page 157: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

vector<string> TelephoneDirectory::find_entries(int number){ multimap<int, string>::iterator lower = inverse_database.lower_bound(number); multimap<int, string>::iterator upper = inverse_database.upper_bound(number); vector<string> result; for (multimap<int, string>::iterator pos = lower; pos != upper; pos++) { result.push_back(pos->second); } return result;}

Mapsch14/tele.cpp

Page 158: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

void TelephoneDirectory::print_all(){ for (map<string, int>::iterator pos = database.begin(); pos != database.end(); pos++) { cout << pos->first << ": " << pos->second << endl; }}

Mapsch14/tele.cpp

Page 159: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

int main(){ TelephoneDirectory data; data.add_entry("Fred", 7235591); data.add_entry("Mary", 3841212); data.add_entry("Sarah", 3841212); cout << "Number for Fred: " << data.find_entry("Fred") << endl; vector<string> names = data.find_entries(3841212); cout << "Names for 3841212: "; for (int i = 0; i < names.size(); i++) { cout << names[i] << " "; } cout << endl; cout << "All names and numbers:" << endl; data.print_all(); return 0;}

Mapsch14/tele.cpp

Page 160: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Apriority_queue

is a container optimized for one special task:

quickly locating the element with the highest priority.

Prioritization is a weaker condition than ordering.

In a priority_queue the orderof the remaining elements is irrelevant,

it is only the highest priority elementthat is important.

Priority Queues

Page 161: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

To use the priority_queue class in the standard library,you #include the queue header.

#include <queue>

Priority Queues

Page 162: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Here the priority_queue contains strings denoting tasks.The strings are formatted so that they start with a priority number.We will want to retrieve and remove the task with the top priority:

#include <queue>

priority_queue<string> tasks;tasks.push("2 - Shampoo carpets");tasks.push("9 - Fix overflowing sink");tasks.push("5 - Order cleaning supplies");

string task = tasks.top(); // Returns "9 - Fix overflowing sink“tasks.pop();

Priority Queues

Page 163: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

The push method inserts a value into the priority_queue then internally the tree rearranges its data so that the highest priority is always on “top.”The top method returns the value with the highest priority.The pop method removes the value with the highest priority.

#include <queue>

priority_queue<string> tasks;tasks.push("2 - Shampoo carpets");tasks.push("9 - Fix overflowing sink");tasks.push("5 - Order cleaning supplies");

string task = tasks.top(); // Returns "9 - Fix overflowing sink“tasks.pop();

Priority Queues

Page 164: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

#include <iostream>#include <queue>using namespace std;

class WorkOrder{public: WorkOrder(int priority, string description); int get_priority() const; string get_description() const;private: int priority; string description;};

Priority Queuesch14/pqueue.cpp

Page 165: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

WorkOrder::WorkOrder(int pr, string descr){ priority = pr; description = descr;}

int WorkOrder::get_priority() const{ return priority;}

bool operator<(WorkOrder a, WorkOrder b){ return a.get_priority() < b.get_priority(); }

Priority Queuesch14/pqueue.cpp

Page 166: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

int main(){ priority_queue<WorkOrder> tasks; tasks.push(WorkOrder(2, "Shampoo carpets")); tasks.push(WorkOrder(3, "Empty trash")); tasks.push(WorkOrder(2, "Water plants")); tasks.push(WorkOrder(1, "Remove pencil sharpener shavings")); tasks.push(WorkOrder(4, "Replace light bulb")); tasks.push(WorkOrder(9, "Fix overflowing sink")); tasks.push(WorkOrder(1, "Clean coffee maker")); tasks.push(WorkOrder(5, "Order cleaning supplies")); while (tasks.size() > 0) { WorkOrder task = tasks.top(); tasks.pop(); cout << task.get_priority() << " - " << task.get_description() << endl; } return 0;}

Priority Queuesch14/pqueue.cpp

Page 167: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Notice that we had to tell the priority_queuehow to compare our WorkOrder objects.

Normally STL containers will use <but that has no meaning for WorkOrder objects.

bool operator<(WorkOrder a, WorkOrder b){ return a.get_priority() < b.get_priority(); }

We overloaded opertator<() to do the correct comparison for the type stored in the priority_queue.

This gives “new meaning” to <!

Priority Queues

Page 168: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Overloading opertator<() also worksfor sets and multisets

if we need an ordering other thanthe default meaning of <

Priority Queues

Page 169: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

One obvious implementation fora priority_queue is a sorted set.

Then it is an easy matterto locate and remove the largest element.

However, another data structure,called a heap,

is even more suitable for implementing priority queues.

Priority Queues

Page 170: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

A heap (or, for greater clarity, max-heap)is a binary tree with two special properties:

A heap is an almost complete tree: all nodes are filled in, except the last level may have some nodes missing toward the right

The tree fulfills the heap property: all nodes store values that are at least as large as the values stored in their descendants

Heaps

Page 171: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Almost complete tree:all nodes are filled except at the bottom right

Heaps

Page 172: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Almost complete tree:all nodes are filled except at the bottom right

Fulfills the heap property:each node >= all descendants

Heaps

<= 80

Page 173: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Almost complete tree:all nodes are filled except at the bottom right

Fulfills the heap property:each node >= all descendants

Heaps

<= 25 <= 57

Page 174: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Almost complete tree:all nodes are filled except at the bottom right

Fulfills the heap property:each node >= all descendants

Heaps

<= 16 <= 10

Page 175: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

A heap is superficially similar to a binary search tree,but there are two important differences:

The shape of a heap is very regular. Binary search trees can have arbitrary shapes.

In a heap, the left and right subtrees both store elements that are smaller than the root element. In contrast, in a binary search tree, smaller elements are stored in the left subtree and larger elements are stored in the right subtree.

Heaps

Page 176: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Suppose we have a heap and want to insert a new element.

After the insertion, the heap property should again be fulfilled.

Heaps

Page 177: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

First, add a vacant slot to the end of the tree.(Remember to keep the tree almost complete.)

Heaps

Page 178: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

First, add a vacant slot to the end of the tree.Next, demote the parent of the empty slot if it is smaller than the element to be inserted. That is, move the parent value into the vacant slot, and move the vacant slot up.

Heaps

Page 179: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Repeat this demotion as long as the parent of the vacant slot issmaller than the element to be inserted.

Heaps

Page 180: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

At this point, either the vacant slot is at the root, or the parent ofthe vacant slot is larger than the element to be inserted. Insert the element into the vacant slot.

Heaps

Page 181: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

At this point, either the vacant slot is at the root, or the parent ofthe vacant slot is larger than the element to be inserted. Insert the element into the vacant slot.

Heaps

Page 182: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

We will not consider an algorithm forremoving an arbitrary node from a heap.

The only node that we will remove is the root node,which contains the maximum of all of the values in the heap.

Heaps

Page 183: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

The algorithm is:

Extract the root node value.

Move the value of the last node of the heap into the root node, and remove the last node. Now the heap property may be violated for the root node, because one or both of its children may be larger.

--------- At this point we may need to “fix the heap”.

Promote the larger child of the root node. Now the root node again fulfills the heap property.

Heaps

Page 184: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Repeat this process with the demoted child.That is, promote the larger of its children.Continue until the demoted child has no larger children.The heap property is now completely fulfilled.

Heaps

Page 185: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Heaps

Page 186: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Heaps

Page 187: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Heaps

Page 188: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Heaps

Page 189: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Heaps have another major advantage.

Because of the regular layout of the heap nodes,it is easy to store the node values in an array.

First store the first layer, then the second, and so on.

For convenience,we leave the 0 element of the array empty.

Then the child nodes of the node with index ihave index 2 · i and 2 · i + 1,

and the parent node of the node with index ihas index i/2.

Heaps

Page 190: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Heaps

Page 191: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Here is the code for heapusing an array implementation:

(OK, a vector, instead of an array.)

Heaps

Page 192: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

#include <iostream>#include <vector>using namespace std;

/**This class implements a heap.*/

class Heap{public: /** Constructs an empty heap. */ Heap();

HeapsCh14/heap.cpp

Page 193: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

/** Adds a new element to this heap. @param new_element the element to add */ void push(int new_element);

/** Gets the maximum element stored in this heap. @return the maximum element */ int top() const; /** Removes the maximum element from this heap. */ void pop();

Heapsch14/heap.cpp

Page 194: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

/** Returns the number of elements in this heap. */ int size() const;

private: /** Turns the tree back into a heap, provided only the root node violates the heap condition. */ void fix_heap();

/** Returns the index of the left child. @param index the index of a node in this heap @return the index of the left child of the given node */ int get_left_child_index(int index);

Heapsch14/heap.cpp

Page 195: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

/** Returns the index of the right child. @param index the index of a node in this heap @return the index of the right child of the given node */ int get_right_child_index(int index); /** Returns the index of the parent. @param index the index of a node in this heap @return the index of the parent of the given node */ int get_parent_index(int index);

/** Returns the value of the left child. @param index the index of a node in this heap @return the value of the left child of the given node */ int get_left_child(int index);

Heapsch14/heap.cpp

Page 196: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

/** Returns the value of the right child. @param index the index of a node in this heap @return the value of the right child of the given node */ int get_right_child(int index);

/** Returns the value of the parent. @param index the index of a node in this heap @return the value of the parent of the given node */ int get_parent(int index);

vector<int> elements;

};

HeapsCh14/heap.cpp

Page 197: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Heap::Heap(){ elements.push_back(0);}

void Heap::push(int new_element){ // Add a new leaf elements.push_back(0); int index = elements.size() - 1;

// Demote parents that are smaller than the new element while (index > 1 && get_parent(index) < new_element) { elements[index] = get_parent(index); index = get_parent_index(index); } // Store the new element into the vacant slot elements[index] = new_element;}

HeapsCh14/heap.cpp

Page 198: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

int Heap::top() const{ return elements[1];}

void Heap::pop(){ // Remove last element int last_index = elements.size() - 1; int last = elements[last_index]; elements.pop_back(); if (last_index > 1) { elements[1] = last; fix_heap(); }}

Heapsch14/heap.cpp

Page 199: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

int Heap::size() const{ return elements.size() - 1;}

void Heap::fix_heap(){ int root = elements[1];

int last_index = elements.size() - 1;

Heapsch14/heap.cpp

Page 200: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

// Promote children of removed root // while they are larger than last int index = 1; bool more = true; while (more) { int child_index = get_left_child_index(index); if (child_index <= last_index) { // Get larger child

// Get left child first int child = get_left_child(index);

// Use right child instead if it is larger if (get_right_child_index(index) <= last_index && get_right_child(index) > child) { child_index = get_right_child_index(index); child = get_right_child(index); }

Heapsch14/heap.cpp

Page 201: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

// Check if smaller child is larger than root if (child > root) { // Promote child elements[index] = child; index = child_index; } else { // Root is larger than both children more = false; } }

Heapsch14/heap.cpp

Page 202: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

else { // No children more = false; } }

// Store root element in vacant slot elements[index] = root;}

int Heap::get_left_child_index(int index){ return 2 * index;}

int Heap::get_right_child_index(int index){ return 2 * index + 1;}

Heapsch14/heap.cpp

Page 203: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

int Heap::get_parent_index(int index){ return index / 2;}

int Heap::get_left_child(int index){ return elements[2 * index];}

int Heap::get_right_child(int index){ return elements[2 * index + 1];}

int Heap::get_parent(int index){ return elements[index / 2];}

Heapsch14/heap.cpp

Page 204: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

int main(){ Heap tasks; tasks.push(2); tasks.push(3); tasks.push(2); tasks.push(1); tasks.push(4); tasks.push(9); tasks.push(1); tasks.push(5);

while (tasks.size() > 0) { int task = tasks.top(); tasks.pop(); cout << task << endl; } return 0;}

Heapsch14/heap.cpp

Page 205: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Chapter Summary

Page 206: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reserved

Chapter Summary

Page 207: Chapter14 fix

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley &

Sons. All rights reservedSlides by Evan Gallagher

Chapter Fourteen: Sets, Maps, and Priority Queues