Searching: Binary Trees and Hash Tables

Download Report

Transcript Searching: Binary Trees and Hash Tables

Associative Containers
Gordon College
Prof. Brinton
1
STL - Assoc. Containers
• Set
– The key is the data
set<int> intSet;
set<string> keyword;
set<time24> timeSet;
key field
other fields
record object
To support the STL container - set; the programmer must
overload the == operator and < operator by comparing
the key field and giving a Boolean result.
2
STL - Assoc. Containers
• Map
– Stores entries as key-value pair.
– In a pair, the first component is the key; the second
is the value. Each component may have a different
data type.
key
value
map<int, record> studentFile;
studentFile[2343554] = new studentFile;
studentFile[2343554].addToBalance(112);
3
Set and Map
• Both containers do not allow duplicate keys.
• Multiset and multimap (also STL containers)
allow duplicate keys)
4
STL sets and maps
1
2
2
3
4
1
4
5
Degenerate search tree
3
5
red-black tree
5
CLASS set
Constructors
<set>
set();
Create an empty set. This is the Default Constructor.
set(T *first, T *last);
Initialize the set by using the address range [first, last).
CLASS set
Operations
<set>
bool empty() const;
Is the set empty?
int size() const;
Return the number of elements in the set.
6
CLASS set
Operations
<set>
int count(const T& key) const;
Search for key in the set and return 1 if it is in the set and 0
otherwise.
iterator find(const T& key);
Search for key in the set and return an iterator pointing at it, or
end() if it is not found.
Const_iterator find(const T& key) const;
Constant version.
7
CLASS set
Operations
<set>
pair<iterator, bool> insert(const T& key);
If key is not in the set, insert it and then return a pair whose
first element is an iterator pointing to the new element and
whose second element is true. Otherwise, return a pair whose
first element is an iterator pointing at the existing element and
whose second element is false.
Postcondition: The set size increases by 1 if key is
not in the set.
int erase(const T& key);
If key is in the set, erase it and return 1; otherwise, return 0.
Postcondition: The set size decreases by 1 if key is
in the set.
8
CLASS set
Operations
<set>
void erase(iterator pos);
Erase the item pointed to by pos.
Preconditions: The set is not empty, and pos points
to a valid set element.
Postcondition: The set size decreases by 1.
void erase(iterator first, iterator last);
Erase the elements in the range [first, last).
Precondition: The set is not empty.
Postcondition: The set size decreases by the number
of elements in the range.
9
CLASS set
Operations
<set>
iterator begin();
Return an iterator pointing at the first member in the set.
const_iterator begin(const);
Constant version of begin().
iterator end();
Return an iterator pointing just past the last member in the set.
const_iterator end() const;
Constant version of end().
10
Set operations
8
• Union
setC = setA + setB;
setC = 1 2 3 4 5 6 7 8 11 15
• Intersection
A*B
setC = setA * setB;
setC = 1 3 5 7 8 11
• Difference
setC = setA - setB;
setC = 1 4
8
1
5
3
6
11
5
3
15
11
2
7
4
7
11
Map
•
•
•
•
•
•
•
•
swap
begin
end
size
empty
operator[]
find
erase
12
#include <string.h>
#include <iostream>
#include <map>
#include <utility>
using namespace std;
int main()
{
map<int, string> Employees;
Employees[5234] = "Mike C.";
Employees[3374] = "Charlie M.";
Employees[1923] = "David D.";
Employees[7582] = "John A.";
Employees[5328] = "Peter Q.";
cout << "Employees[3374]=" << Employees[3374] << endl << endl;
cout << "Map size: " << Employees.size() << endl;
for( map<int,string>::iterator ii=Employees.begin(); ii!=Employees.end(); ++ii)
{
cout << (*ii).first << ": " << (*ii).second << endl;
}
}
13
#include <string.h>
#include <iostream>
#include <map>
#include <utility>
using namespace std;
int main()
{
map<int, string> Employees;
Employees[5234] = "Mike C.";
Employees[3374] = "Charlie M.";
Employees[1923] = "David D.";
Employees[7582] = "John A.";
Employees[5328] = "Peter Q.";
Employees[3374]=Charlie M.
Map size: 5
1923: David D.
3374: Charlie M.
5234: Mike C.
5328: Peter Q.
7582: John A.
cout << "Employees[3374]=" << Employees[3374] << endl << endl;
cout << "Map size: " << Employees.size() << endl;
for( map<int,string>::iterator ii=Employees.begin(); ii!=Employees.end(); ++ii)
{
cout << (*ii).first << ": " << (*ii).second << endl;
}
}
14
#include <string.h>
#include <iostream>
#include <map>
#include <utility>
using namespace std;
int main()
{
map<string, int> Employees;
Employees["Mike C."] = 5234;
Employees["Charlie M."] = 3374;
Employees.insert(std::pair<string,int>("David D.",1923));
Employees.insert(map<string,int>::value_type("John A.",7582));
Employees.insert(std::make_pair("Peter Q.",5328));
cout << "Map size: " << Employees.size() << endl;
for( map<string, int>::iterator ii=Employees.begin(); ii!=Employees.end(); ++ii)
{
cout << (*ii).first << ": " << (*ii).second << endl;
}
}
15
#include <string.h>
#include <iostream>
#include <map>
#include <utility>
using namespace std;
Map size: 5
Charlie M.: 3374
David D.: 1923
John A.: 7582
Mike C.: 5234
Peter Q.: 5328
int main()
{
map<string, int> Employees;
Employees["Mike C."] = 5234;
Employees["Charlie M."] = 3374;
Employees.insert(std::pair<string,int>("David D.",1923));
Employees.insert(map<string,int>::value_type("John A.",7582));
Employees.insert(std::make_pair("Peter Q.",5328));
cout << "Map size: " << Employees.size() << endl;
for( map<string, int>::iterator ii=Employees.begin(); ii!=Employees.end(); ++ii)
{
cout << (*ii).first << ": " << (*ii).second << endl;
}
}
16
struct cmp_str
{
bool operator()(char const *a, char const *b)
{
return std::strcmp(a, b) < 0;
}
};
int main()
{
map<char *, int, cmp_str> Employees;
Employees["Mike C."] = 5234;
Employees["Charlie M."] = 3374;
Employees.insert(std::pair<char *,int>("David D.",1923));
Employees.insert(map<char *,int>::value_type("John A.",7582));
Employees.insert(std::make_pair((char *)"Peter Q.",5328));
cout << "Map size: " << Employees.size() << endl;
for( map<char *, int, cmp_str>::iterator ii=Employees.begin(); ii!=Employees.end(); ++ii)
{
cout << (*ii).first << ": " << (*ii).second << endl;
}
}
17
struct cmp_str
{
bool operator()(char const *a, char const *b)
{
return std::strcmp(a, b) < 0;
}
};
int main()
{
map<char *, int, cmp_str> Employees;
Employees["Mike C."] = 5234;
Employees["Charlie M."] = 3374;
Employees.insert(std::pair<char *,int>("David D.",1923));
Employees.insert(map<char *,int>::value_type("John A.",7582));
Employees.insert(std::make_pair((char *)"Peter Q.",5328));
cout << "Map size: " << Employees.size() << endl;
Map size: 5
Charlie M.: 3374
David D.: 1923
John A.: 7582
Mike C.: 5234
Peter Q.: 5328
for( map<char *, int, cmp_str>::iterator ii=Employees.begin(); ii!=Employees.end(); ++ii)
{
cout << (*ii).first << ": " << (*ii).second << endl;
}
}
18
Map details
• Associative Arrays
M[“Computer Science”] = 20;
Keys are unique therefore:
M[“Computer Science”] = 26;
replaces the value in the tree for CS.
19
Map details
• Creating a map:
#include <map>
int main()
{
map<string, double> A;
…
20
Map Details
• [ ] operator
Steps
1. Search the for map for key
2. If key found, return a reference to the
value object associated with key.
3. If key not found, create a new object
of type value associated with key,
and return a reference to that.
21
Map Details
•
[ ] operator
int salary = Employee[“Jack Smith”];
Caution: this will create a new tree entry if it
doesn’t exist and assign 0 to variable
salary
22
Map Details
•
[ ] operator
Better technique:
if (( itr = Employee.find(“Jack Smith”)) ==
Employee.end())
cout << “ the employee does not exist.” << endl;
Else
cout << “Employee Salary: “ << itr->second << endl;
23
Map Details
•
Pair Class
1. Must include <utility>
2. Contains two public members, first and second
3. Store key/value association
itr->first
itr->second
24
Map Details
•
Pair Class
Easiest way to construct pair:
pair<string, int> a;
a = make_pair(string(“Jack Smith”), int(100000));
25
Map Details
•
Element requirements:
Each key and value must be assignable (an assignment operator
which performs a “deep copy”
Deep copy
target of the assignment should be equal but independent of the
source
a = b;
the value of a should match b - however if you change a it should
not affect b (and vice versa)
Note: if we talking about a linked list then a shallow copy would
have two pointers pointing to the same list.
26
Map Details
•
Element requirements:
Also each key should adhere to “weak ordering”:
1. A<A is false
2. Equality can be determined with (!(A<B) && !(B<A))
Note: only using the less than operator
3. If A<B and B<C then A<C must be true
int, char, double, etc. (built-in types) are strict weak ordered
27
Map Details
•
Element requirements:
value type used must have a defined default constructor.
map <int, bigNumber>
The built in types have a type of default constructor:
map<int, string>
28
Map Details
Operation Description
swap
Swaps elements with another map. This
operation is performed in constant time.
Time
Complexity
O(1)
Ex: map1.swap(map2);
begin
Returns an iterator to the first pair in the
map.
O(1)
Ex: itr = map1.begin();
end
Returns an iterator just beyond the end of
the map.
O(1)
29
Map Details
Operation Description
size
Returns the number of elements
contained by the map. You should use
empty() to test whether or not size equals
0, because empty() may be much faster.
Time
Complexity
O(n)
cout << map1.size();
empty
Returns true if the map contains zero
elements.
O(1)
Operator [ ]
Accepts a key and returns a reference to
the object associated with key. Note that
this operator always creates an element
associated with key if it does not exist.
O(log n)
30
Map Details
Operation Description
find
Accepts a key and returns an iterator to the
pair element if found. If the key is not found in
the map, this method returns end().
Time
Complexity
O(log n)
if ( (itr = map1.find("Bob")) == map1.end())
cerr << "Bob was not found in the map." << endl;
else
cout << "Bob was found in the map." << endl;
31
Map Details
Operation Description
erase
There are three overloaded forms of this method.
Time
Complexity
O(1)
The first accepts a single iterator, and removes the
element implied by the iterator from the map. The
map should be non-empty. O(1).
Ex: assert(!map1.empty());
map1.erase(map1.begin()); // remove the first
element
32
Map Details
Operation Description
erase
There are three overloaded forms of this method.
Time
Complexity
O(n)
The second accepts two iterators, that specify a
range of values within the map to be removed. The
time complexity is logarithmic plus linear time for the
length of the sequence being removed. The two
iterators must be valid iterators within the sequence
contained by the map. Formally, the range of values
[starting, ending) are removed. At worst, this is an
O(n) operation.
Ex: map1.erase(map1.begin(), map1.end()); // erase
the entire map
33
Map Details
Operation Description
erase
There are three overloaded forms of this method.
Time
Complexity
O(log n)
The last accepts an object of the key type, and
removes all occurrences of the key from map. Note
that since map elements all have unique keys, this
will erase at most 1 element. O(log n).
Ex: map1.erase(string("Bob")); // removes all
occurences of "Bob"
34
Multiset
Allow multiple items with same key
35
Multiset Details
Operation
Description
constructor
creates an empty multiset
size
multiset<int> S
returns the number of elements
S.size()
insert
S.insert( const T& ) : adds an item to the
set. If the item is already present, there will
be multiple copies in the multiset..
S.insert(6);
36
Multiset Details
Operation
Description
count
S.count( const T& t ) : returns the number of
times that the item t is found in the set. This
will be 0 if the item is not found
S.erase( const T& t ) : removes the all items
equal to t from the multiset.
erase
erase
S.erase( multiset<T>::iterator i ) : removes
the item pointed to by i.
37
Multiset Details
Operation
Description
reverse
reverse( iterator begin, iterator end ) : reverses the
order of the items:
S.erase( v );
// ALL: removes all of items == v
from the multiset
S.erase( S.find( v ) ); // ONE: removes the first item
== v from the multiset
find
S.find( const T& t ) : returns an iterator that
points to the first item == t, or S.end() if the
item could not be found.
38
Multiset Details
Operation
Description
begin
S.begin() : returns an iterator that points to
the first element of S. Note that this is the
smallest item in the multiset, because the
multiset is always stored in sorted order.
end
S.end() : returns an iterator that points just
past the last element of S. Note that this is
the largest item in the multiset, because the
multiset is always stored in sorted order.
39
Multiset Details
Operation
Description
equal_range S.equal_range(*iter) - returns a pair of
iterators such that all occurrences of the
item are in the iterator range
pair<multiset <int>::iterator, multiset <int>::iterator > p;
p = S.equal_range(5);
40