Chapter14 fix

Preview:

Citation preview

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

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

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.

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;

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.

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

Sons. All rights reserved

Sets

#include <set>…

set<string> names;

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

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;

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 ) ...

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

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

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.

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

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…

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.

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…

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.

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; } }}

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…

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:

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

Sons. All rights reserved

Binary Search TreesTREES!

Upside down trees!

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

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

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

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.

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

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

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.

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.

< <

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

Sons. All rights reserved

Binary Search Trees

This is a binary search tree.

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

Sons. All rights reserved

Let’s verify this.

Binary Search Trees

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

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.

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!),

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?

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

Sons. All rights reserved

Binary Search Trees

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

<

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

Sons. All rights reserved

Binary Search Trees

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

<

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

Sons. All rights reserved

Binary Search Trees

What about theright descendants’ data?

<

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

Sons. All rights reserved

Binary Search Trees

< <

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

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

Sons. All rights reserved

Binary Search Trees

< <

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

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.

< <

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

Sons. All rights reserved

Binary Search Trees

“Adam” < “Eve”?

<

< <

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

Sons. All rights reserved

Binary Search Trees

“Adam” < “Eve”?Yes.

<

< <

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”?

< <

<

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

Sons. All rights reserved

Binary Search Trees

Eve”< “Harry”?

<

< <

<

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

Sons. All rights reserved

Binary Search Trees

Eve”< “Harry”?Yes.

<

< <

<

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”.

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

Sons. All rights reserved

Binary Search Trees

There are none.

<

< <

<

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.

<

< <

<

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”.

<

< <

<

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

Sons. All rights reserved

Binary Search Trees

There are none.

<

< <

<

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.

<

< <

<

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.

< <

<<

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

Sons. All rights reserved

Binary Search Trees

This node has noleft descendants.

< <

<<

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

Sons. All rights reserved

Binary Search Trees

So “Romeo” is in order.

< <

<<

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

Sons. All rights reserved

Binary Search Trees

Now for the right descendants.

< <

<<

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

Sons. All rights reserved

Binary Search Trees

“Romeo” < “Tom”?

<

<<<

<

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

Sons. All rights reserved

Binary Search Trees

“Romeo” < “Tom”?

Yes.

<

<<<

<

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

Sons. All rights reserved

Binary Search Trees

<

<<<

The node with “Tom”has no descendants,

<

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.

<

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

Sons. All rights reserved

Binary Search Trees

This tree has theBinary Search Tree

properties.

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

Sons. All rights reserved

Binary Search Trees

<

<<<

This tree has theBinary Search Tree

properties.

<

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;};

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

Sons. All rights reserved

Binary Search Trees There is one BinarySearchTree

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.

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.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Sons. All rights reserved

Binary Search Trees

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

Sons. All rights reserved

Binary Search Trees

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

Sons. All rights reserved

Binary Search Trees

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

Sons. All rights reserved

Binary Search Trees

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

Sons. All rights reserved

Binary Search Trees

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

Sons. All rights reserved

Analysis time!Binary Search Trees

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

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

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.

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!

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

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

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

Sons. All rights reserved

Binary Search Trees

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Sons. All rights reserved

Done!

Tree Traversal

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

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

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

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

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

Sons. All rights reserved

The code for all of these activities:

Tree Traversal

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Sons. All rights reserved

Map

Maps

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Sons. All rights reserved

The map header file also has multimap .

#include <map>

Maps

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Sons. All rights reserved

Heaps

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

Sons. All rights reserved

Heaps

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

Sons. All rights reserved

Heaps

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

Sons. All rights reserved

Heaps

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

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

Sons. All rights reserved

Heaps

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Sons. All rights reserved

Chapter Summary

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

Sons. All rights reserved

Chapter Summary

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

Sons. All rights reservedSlides by Evan Gallagher

Chapter Fourteen: Sets, Maps, and Priority Queues