Title: STL Other Structures Vectors, Sets, Maps, Stacks, Queues, Deques, Priority Queues
1STL Other Structures Vectors, Sets, Maps,
Stacks, Queues, Deques, Priority Queues
2Vector
- The vector container resembles a C array.
- It holds zero or more objects of the same type,
and that each of these objects can be accessed
individually. - Defined as a template class ? hold objects of any
type. -
3Vector
- STL class vector
- include ltvectorgt
- include ltalgorithmgt // for generic algorithms
- element type is templated
- implemented as growable array
4Vector
- include ltvectorgt
- // Define a vector of integers.
- vectorltintgt vec_one
- int a 2 // Some integer data objects
- int b -5
- vec_one.push_back(a) // Add item at end of
vector vec_one.push_back(9) - vec_one.push_back(b) // vec_one 2, 9, -5
- unsigned int indx
- for (indx 0 indx lt vec_one.size() indx)
- cout ltlt vec_oneindx ltlt endl //Write out
vector item
5Member functions
- size_type size() constReturns the number of
items (elements) currently stored in the vector.
The size_type type is an unsigned integral value. - bool empty() constReturns a true value if the
number of elements is zero, false otherwise.
6Member functions
- void push_back(const T x)Adds the element x at
the end of the vector. (T is the data type of the
vector's elements.) - iterator begin()Returns an iterator that
references the beginning of the vector. - iterator end()Returns an iterator that
references a position past the end of the vector.
7Member functions
- void erase(iterator first, iterator last)
- Erase (remove) elements from a vector.
- clear() is an alternate way to do the same
thing. - vectorltintgt a
- ...
- a.erase(a.begin(),a.end()) // Remove all
elements. - a.clear( ) // same thing.
8Operator
- vectorltintgt a
- vectorltintgt b
- a.push_back(5)
- a.push_back(10)
- a.push_back(3)
- b a // The vector b now contains three
elements 5, 10, 3
9Operator
- - Tests whether two vectors have the same
content. -
- - Element-by-element comparison for all
elements)
10Operator
-
- - returns a reference to an element of the
vector. -
-
- vectorltdoublegt vec
- vec.push_back(1.2)
- vec.push_back(4.5)
- vec1 vec0 5.0
- vec0 2.7 // Vector now has two elements
2.7, 6.2 -
11Function at()
-
- at() returns a reference to an element of the
vector. -
- Also performs some bounds-checking!
- vectorltdoublegt vec
- vec.push_back(1.2)
- vec.push_back(4.5)
- vec.at(1) vec.at(0) 5.0
- vec.at(0) 2.7
- // Vector now has two elements 2.7, 6.2
-
12sort ( )
- The sort algorithm is an operation (function)
that can be applied to many STL containers
(except for the list container). - Using it on the vector container class template
- include ltvectorgt
- include ltalgorithmgt // Include algorithms
-
- vectorltintgt vec
- vec.push_back (10) vec.push_back (3)
vec.push_back (7) - sort(vec.begin(), vec.end()) // vector 3, 7,
10
13sort ( )
- Orders the container's contents in ascending
order, as defined by the "less than" (lt) operator
as applied to the vector elements. - If this operator is defined for a
programmer-defined type (as is the case with the
string class), then the programmer-defined type
can be sorted just as easily as a built-in type. - Define lt and your class can be sorted based on
your criteria.
14Other Vector Methods
- default, size, size/init. val, copy constructors
- front(), back() // return elements at either end
- push_back(val), insert(iter, val), swap()
- pop_back()
- remove(val) // all values remove_if(cond)
- empty(), capacity(), size()
- vectoriterator, begin(), end()
15Generic Algorithms for Vectors
- fill (start-iter, stop-iter, value)
- max_element (start-iter, end-iter) // also
min_element() - reverse (start-iter, end-iter)
- count (start-iter, end-iter, value, counter)
- count-if (start-iter, end-iter, unary-func,
counter) - transform (start-iter, end-iter, dest-iter,
unary-func) - copy (src-start-iter, src-end-iter,
dest-start-iter) - find (start-iter, end-iter, value)
- find_if (start-iter, end-iter, func-obj)
- replace (start-iter, end-iter, target, new-val)
- replace_if (start-iter, end-iter, function,
new-val) - sort (start-iter, end-iter)
- for_each (start-iter, end-iter, function)
- iter_swap(iter1, iter2) swap values between two
16Vector Applications
- Storage of digits for large integers
- List of items
- Genes in Chromosome
- Simple database
- Others.
- General array based stuff where you want random
access
17Set
- The STL set is a collection of unique elements of
the same data type. - Only unique elements may be added to a set.
- If you attempt to insert a value that is already
contained in the set, the request is ignored. - The set container provides bidirectional
iterators.
18Set/Multiset Methods
- default, copy constructors, operator
- insert(val)
- erase(val), erase(iter), erase(iter, iter)
- swap(otherSet)
- find(start-iter, end-iter, val)
- empty(), size(), count(val)
- lower_bound(val), upper_bound(val),
equal_range(val) - setiterator, begin(), end(), rbegin(), rend()
19Declaring a Set
- To use the set container, you must include
ltsetgt. - The set container is declared in the std
namespace. - E.g., to declare a set of strings
- include ltsetgt
- include ltstringgt
- using namespace std
- void SomeFunction()
- setltstringgt words
- setltstringgtiterator setItr
-
20Set
- STL class set, multiset
- set no duplicate values allowed
- multiset duplicate values allowed
- include ltsetgt, ltmultisetgt
- element type is templated
- implemented as a binary tree of nodes (for
efficient search/insert/remove) - implemented as ordered collection
21Adding Elements to a Set
- You can add an element to a set by calling the
setinsert() method, invocation - words.insert("radio")
- This adds the string "radio" to the collection
of elements contained by the set. - If you later attempt to insert the string
"radio" again, then the set remains unchanged.
22Testing for Inclusion in the Set
- You can test to see if a value is contained in
the set by calling setfind() , which returns an
iterator to the element if it found, or
setend() if the element is not contained in the
set. - E.g.,
- setltstringgtiterator setItr
-
- if ((setItr words.find("cat")) words.end())
- cerr ltlt "cat was not found in the set.\n"
- else
- cout ltlt "cat was found in the set.\n"
23Testing for Inclusion in the Set
- You can also access the elements of a set by
traversing the set with an iterator. - If you traverse the sequence from beginning to
end, the elements will be accessed in ascending
order. - E.g.,
- for (setItrwords.begin() setItr!words.end()
setItr) - cout ltlt setItr ltlt endl
24swap( )
- Swaps elements with another set.
- This operation is performed in constant time.
- E.g.,
- set1.swap(set2)
25swap( )
- include ltsetgt
- include ltstringgt
- using namespace std
- int main()
- string first ("This is string 1")
- string second ("This is string 2")
- first.swap(second)
- cout ltlt "Set1 " ltlt first ltlt endl
- cout ltlt "Set2 " ltlt second ltlt endl
- return 0
-
- Set1 This is string 2
- Set2 This is string 1
26lower_bound( )
- Returns an iterator to the first element that is
greater than or equal to key. Complexity O(log2
n) - Returns end() if no such element exists.
- setltintgt s
- setltintgt iterator itr
- for (int i0 i lt 5 i)
- s.insert(i2) // Set 0 2 4 6 8
- itr s.lower_bound(4)
- if (itr s.end())
- cout ltlt "No element found" ltlt endl
- else
- cout ltlt "LB is " ltlt itr ltlt endl
- LB is 4
-
27upper_bound( )
- Returns an iterator to the first item greater
than the key. - Returns end() if no such element exists.
- setltintgt s
- setltintgt iterator itr
- for (int i0 i lt 5 i)
- s.insert(i2) // Set 0 2 4 6 8
- itr s.upper_bound(4)
- if (itr s.end())
- cout ltlt "No element found" ltlt endl
- else
- cout ltlt "UB of set is " ltlt itr ltlt endl
-
- UB of set is 6
28size( ) and empty( )
- Returns the number of elements contained by the
set. - cout ltlt s.size()
-
- Use empty() to test whether or not size equals 0,
because empty() may be much faster. - Returns true if the set contains zero elements.
-
29find( )
- Accepts a key and returns an iterator to the
element if found. - If not found in the set ? returns end().
- // assume set Starsky, Hutch, Huggy, Louie
- if ((itr s.find("Louie")) s.end())
- cout ltlt "Louie is sleeping with the
fishes.\n" - else
- cout ltlt "Louie is in the set.\n
- if ((itr s.find("Sammy")) s.end())
- cout ltlt "Sammy is sleeping with the
fishes.\n" else - cout ltlt "Sammy is in the set.\n"
- Louie is in the set
- Sammy is sleeping with the fishes.
30erase( )
- There are three overloaded forms of this method.
- The first accepts a single iterator, and removes
the element implied by the iterator from the set.
The set should be non-empty. O(1). - E.g.,
- assert(!s.empty())
- s.erase(s.begin())
- // remove the first element
31erase( )
- The second accepts two iterators, that specify a
range of values within the set to be removed. - The time complexity is O(log2 n ts) where
- ts llinear time for the length of the
sequence being removed. - The two iterators must be valid iterators within
the sequence contained by the set. Formally, the
range of values starting, ending) are removed.
At worst, this is an O(n) operation. - E.g.,
- s.erase(s.begin(), s.end())
- // erase the entire set
32erase( )
- The last accepts an object of the key type, and
removes all occurrences of the key from set. - Note that since set elements are all unique, this
will erase at most 1 element. O(log n). - s.erase(string(Huggy)) // removes Huggy" from
the set
33erase( )
- // Assume s Starsky Hutch Huggy Louie
- s.erase("Huggy")
- cout ltlt "Set is "
- for (itrs.begin() itr !s.end() itr)
- cout ltlt itr ltlt " "
- cout ltlt endl
- s.erase("Lois") cout ltlt "Set is "
- for (itrs.begin() itr !s.end() itr)
- cout ltlt itr ltlt " "
- cout ltlt endl
- Set is Hutch Louis Starsky // sorted
- Set is Hutch Louis Starsky // do nothing on a
failed erase
34Set Generic Algorithms
- includes(s1.start-iter, s1.end-iter,
s2.start-iter, s2.end-iter) - // subset this is boolean (is s2 a subset of
s1) - set_union(s1.start-iter, s1.end-iter,
s2.start-iter, s2.end-iter, result-start-iter) - set_intersection(s1.start-iter, s1.end-iter,
s2.start-iter, s2.end-iter, result-start-iter) - set_difference(s1.start-iter, s1.end-iter,
s2.start-iter, s2.end-iter, result-start-iter) - // s1 s2
- set_symmetric_difference(s1.start-iter,
s1.end-iter, s2.start-iter, s2.end-iter,
result-start-iter) - // (s1 s2) U (s2 s1)
35set_difference example
int main() int A1 1, 3, 5, 7, 9,
11 int A2 1, 1, 2, 3, 5, 8, 13
const int N1 sizeof(A1) / sizeof(int)
const int N2 sizeof(A2) / sizeof(int)
cout ltlt "Difference of A1 and A2 "
set_difference(A1, A1 N1, A2, A2 N2,
ostream_iteratorltintgt(cout, " ")) The
output is Difference of A1 and A2 7 9 11
36symmetric_set_difference example
int v13 13, 18, 23 int v24
10, 13, 17, 23 int result4 0, 0,
0, 0 set_symmetric_difference ( v1, v1 3,
v2, v2 4, result ) for (
int i 0 i lt 4 i ) cout ltlt result i
ltlt cout ltlt "\n" Output is 10 17 18
0
37Set Applications
- Spell-checker
- Spell-checker with corrections
- Anagrams
- Clusters of similar objects/values
38The Map Class
- Is an example of an associative container.
- Associates, or maps, values of some key type to
values of some other type. - E.g., it is possible to use a map to associate
names represented as strings with some other type
that you chose, such as floating-point values. - This would allow you to associate a person's name
with a bank account balance, grade point average,
etc.
39Map Class
- Associative containers similar to associative
arrays in other programming languages. - E.g., Perl recognizes associative arrays
(hashes) as a fundamental data type in that
language.
40Map Class
- The map container allows you to directly access
elements based upon a key value - aMap"John Doe" 3.2
- Each key must be unique. For example,
- aMap"John Doe" 6.4
- would replace whatever value was previously
associated with the string "John Doe" with 6.4.
41Map Class
- Must include ltmapgt
- To declare an instance of a map, you must pass
the key type and the value type as template
parameters. - Like all of the C Standard Library, map is part
of the std namespace.
42Map Class
- To declare a map that associates strings with
doubles - include ltmapgt
- using namespace std
- void SomeFunction()
- mapltstring, doublegt aMap
-
-
43Map Class
- Be careful when using a map as an associative
array. - The operator may not have the semantics you
think it should. - Operator for map uses this basic algorithm
- 1. Search the map for key.
- 2. If key is found, return a reference to the
value object associated with key. - 3. If not found, create a new object of type
value associated with key, and - return a reference to that.
44Map Class
- Whether the operator is used in an expression
or not, it will create a new object of the value
type if the key is not found and return a
reference to it. - These are often not the desired semantics, as in
- double GPA aMap"John Doe" // Wrong!
- aMap"John Doe" will be created if it does not
exist and default to 0.0!
45Map Class
- Instead, use find() method of map to search for
an element that matches key, but will not create
the element if it does not exist. - The find() method returns an iterator to a pair
object, or mapend() if the key was not found. - The first member of the pair contains the key and
the second member of the pair contains the value
associated with key.
46Pair Class
- The find() method returns an iterator to a pair
object. - The pair class template, declared in ltutilitygt,
contains two objects of specific types. - Pair objects have two public members, first and
second, which provide access to the elements that
comprise a pair. - The map class template uses key/value pairs to
store the key/value associations. - pairfirst represents the key,
- pairsecond represents the value associated
with key.
47Map
- The easiest way to construct a pair is with the
convenience function template make_pair(). - It accepts two objects, and returns a pair that
contains copies of those two objects. - E.g.,
- pairltstring,doublegt p
- p make_pair(string("Microsoft Share Price"),
double(85.27))
48Map/Pair Example
- E.g.,
- mapltstring, doublegtiterator itr
-
- if ((itr aMap.find("John Doe")) aMap.end())
- cerr ltlt "John Doe not found." ltlt endl
- else
- cout ltlt "John Doe has a " ltlt itr-gtsecond
- ltlt " GPA" ltlt endl
49Map
- The map class template requires that key and
value types be assignable, i.e., these types
should have an assignment operator that does what
it should, such as performing a deep copy if
necessary. - The target of an assignment must be independent
but equal to the source of the assignment.
50Map
- The independence property should be carefully
observed. - For example, after the assignment ab ,
- a change to b should not affect a.
- If a and b were linked lists and a shallow copy
was used to perform the assignment, then a and b
would not be independent. - The element class must support deep copies, if
you want to avoid problems!
51Map
- The key type used in a map must adhere to strict
weak ordering. Strict weak ordering means - 1. alta is false.
- 2. Equality can be determined by the expression
- (!(altb) !(blta))
- That is, equality can be determined using only
the less than operator. - 3. If altb and bltc, then altc must be true
(transitivity).
52Map
- Note that a, b, and c are objects of the key
type, and the less than operator is assumed to be
used when comparing two objects. - Any type that does not satisfy the above three
rules is not a strict weak ordered type. Note
that the built-in data types (char, int, double,
etc.) are all strict weak ordered types.
53Methods for Map
- Assume the following for subsequent examples
- mapltstring, doublegt map1
- mapltstring, doublegt map2
- mapltstring, doublegtiterator itr
54Methods for Map
- swap( ) - swaps elements with another map.
- This operation is performed in constant time.
- map1.swap(map2)
- begin( ) - returns an iterator to the first pair
in the map - itr map1.begin()
- end( ) - returns an iterator that is just beyond
the end of the map.
55Methods for Map
- size( )
- - returns the number of elements contained by the
map. - Use empty() to test whether or not size equals
0, - because empty() may be much faster.
- cout ltlt map1.size()
- empty( )
- - returns true if the map contains zero
elements. -
56Operator Method
- Accepts a key and returns a reference to the
object associated with key. O(log2 n) - This operator always creates an element
associated with key if it does not exist.
57find( ) Method
- 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() - if ((itr map1.find("Bob")) map1.end())
- cerr ltlt "Bob was not found in the map.\n"
- else
- cout ltlt "Bob was found in the map.\n"
58erase( ) Method
- There are three overloaded forms of this method.
- 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). - assert(!map1.empty())
- map1.erase(map1.begin()) // remove the first
element
59erase( ) Method
- 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. - map1.erase(map1.begin(), map1.end())
- // erase the entire map
60erase( ) Method
- The third 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(log2
n). - map1.erase(string("Bob"))
- // removes all occurences of "Bob"
61Maps and Multimaps
- Map a collection of name-value pairs
- STL class mapltkey-type, value-typegt
- Multimap a map with multiple values allowed for
same key - STL class multimapltkey-type, value-typegt
- map is inherited from set
62Map Applications
- Telephone Directory
- Sentence Generation
- Database Index key/entire record pointer
- Concordance/Book Index
63Stacks / Queues
- Stack a last-in-first-out (LIFO) structure
- Queue a first-in-first-out (FIFO) structure
- include ltstackgt, ltqueuegt
- template ltelement-type, container-typegt
- e.g. stackltintgt // defaults to deque
- stackltdouble, listltdoublegt gt
- (same for queue)
- stack and queue are other instances of an adaptor
- stack supports 3 containers list, vector, deque
- queue supports 2 containers list, deque
64Stack Methods
- empty()
- push()
- void pop()
- T top()
- int size()
65Stack Generic Algorithms
- none additional that are generally used
66Stack Applications - Expressions
- Three Expression Types
- Prefix operator operand1 operator2
- E.g. 2 3 4
- No parentheses needed
- Infix operand1 operator operand2
- E.g. (2 3) 4
- Parentheses need to force precedence of weak
operators - Postfix operand1 operand2 operator
- E.g. 2 3 4
- No parentheses needed
67Stack Applications - Expressions
- Evaluating Postfix Expressions
- While not end of expression
- If operand then push
- If operator then pop 2nd, pop 1st, apply
operator, push result - Converting Infix to Postfix
- Need to pop operators until get to one of lower
precedence on stack - Converting Prefix to Postfix
- Need to track count of operands for each operator
68Stack Applications - Others
- Balancing Parentheses
- While not end of file
- If left parenthesis, push
- If right parenthesis
- If not empty then pop else error (no left for
right) - If not empty then error (no right for left)
- Converting Bases (e.g. Base 10 -gt Base 2)
- Function Call Stack
- Web Spider (holding links for later examination)
69Stack Declaration
- To declare a stack that uses list as the
underlying container - include ltstackgt
- include ltlistgt
- using namespace std
- stackltint, stdlistltintgt gt myStack
70Stack Declaration
- To declare a stack that uses list as the
underlying container - include ltstackgt
- include ltlistgt
- using namespace std
- stackltint, stdlistltintgt gt myStack
- Note that the second template argument defaults
to - dequeltvalue_typegt
71Stack Methods
- empty( )
- Returns true if the stack is empty
- stackltintgt stack1
- if (stack1.empty())
- cout ltlt "The stack is empty."
- size( )
- Returns the number of elements contained by the
stack. - cout ltlt stack1.size()
72Stack Methods
- top( )
- Returns a reference to the top element on the
stack. You must ensure that the stack is not
empty before invoking this method. - if (!stack1.empty())
- cout ltlt stack1.top
73Stack Methods
- push( )
- Inserts an element at the top of the stack.
- This is the only operation provided to add an
element. - stack1.push(64)
- pop( )
- Removes the top element of the stack. The stack
should not be empty. - if (!stack1.empty())
- stack1.pop()
74Queue Methods
- empty()
- push()
- void pop()
- T front() // these two replace top()
- T rear() //
- int size()
75Queue Generic Algorithms
- none additional that are generally used
76Queue Applications
- Printer
- Processor
- Simulations of real-world line domains
- Bank tellers
- Customer service reps through phones
- Help desk
- Ring buffers
77Deque
- Deque a structure that support efficient insert
and remove operations at both ends - short for double ended queue
- pronounced either deck or dq
- include ltdequegt
- template ltelement-typegt
- e.g., dequeltintgt
78Deque vs. Vector
- Deque allows constant time insertion/removal of
elements from the beginning and end of a
sequence. Vector only allows elements to be
inserted/removed from the end of a sequence in
amortized constant time. - Deque allows elements to be inserted/removed from
arbitrary points in a sequence more efficiently
than a vector can, although not in constant time.
- Random access to elements contained in a deque is
slightly less efficient when compared to a vector
due to an additional level of indirection.
79Deque vs. Vector
- For large number of elements, a vector will
allocate one large, contiguous block of memory
while a deque will allocate several, smaller
blocks of memory ? better performance under most
operating systems. - Deques provide all the capabilities needed to
function as a stack or a queue. - Deques grow more efficiently than vectors ? deque
allocates a new block of memory when the memory
buffer is exhausted and begin using it to store
the new elements. - A vector will allocate a new, larger block of
memory to replace the previously used memory
block and copy all of the elements to the new
memory block. Vector's method for expanding is
less efficient.
80Deque Methods
- swap( )
- Swaps elements with another deque. O(1).
- dequeltintgt deque1
- dequeltintgt deque2
- dequeltintgtiterator itr
-
- deque1.swap(deque2)
- operator
- Allows assignment of one deque into another. O(n)
- Both deques must contain elements of the same
data type. - deque1 deque2
81Deque Methods
- begin( )
- Returns an iterator to the first value in the
sequence contained by the deque. O(1). - itr deque1.begin()
- end( )
- Returns an iterator to an object that is one
element beyond the last valid value in the
sequence. - This iterator should not be dereferenced, as it
is intended to - indicate the end of a sequence.
- if (itr deque1.end()) // end of sequence
detected
82Deque Methods
- front( )/back( )
- Returns the first/last element in the deque.
O(1). - size( )
- Returns the size of the deque, i.e., the number
of elements it contains. O(1). - empty( )
- Returns true if the deque is empty. O(1).
83Deque Methods
- push_front( )
- Inserts an element at the beginning of the
sequence contained by a deque. O(1) - deque1.push_front(3)
- push_back( )
- Inserts an element at the end of the sequence
contained by a deque.
84Deque Methods
- insert( )
- Inserts a value into the sequence before the
element implied by an iterator. - deque1.insert(itr, 3) // insert the value 3
before itr
85Deque Methods
- erase( )
- There are two forms of this member function.
- The first accepts a single iterator and removes
the element implied by that iterator from the
sequence. - deque1.erase(deque1.begin())
86Deque Methods
- erase( )
- The second is intended to erase a subsequence.
- It accepts a starting and ending iterator and
erases the subsequence from starting, ending). - The time complexity of the operation depends on
the length of the subsequence being erased. - deque1.erase(deque1.begin(), deque1.end())
- // erase the entire deque
87Deque Applications
- Framework for search
- supports both depth-first and breadth-first
search - depth-first search like stack, add and remove
at front - breadth-first search like queue, add at rear,
remove at front - Support as adaptor for other structures
- stack and queue
88Priority Queue
- Priority Queue a structure that support
efficient removal of extreme element, reasonable
insert and remove times - include ltqueuegt // C standard
- is a container adaptor
- template lttype , container , compare-functiongt
- e.g. priority_queueltintgt
- // default 2nd and 3rd arguments vectorltTgt,
lessltTgt this gives us a - // maximum priority queue (remove largest first)
- priority_queuelt int, vector ltintgt gt
- // default 3rd argument lessltTgt this gives
us a maximum priority - // queue also
- priority_queuelt int, vector ltintgt,
greaterltintgt gt //
this gives us a minimum priority queue
89Priority Queue Methods
- empty()
- push()
- void pop() // remove extreme element
- T top() // return extreme element
- int size()
- note same as stack, but different meanings
- by default, extreme is largest, but can invert
the comparison test
90Priority Queue Implementation Possibilities
- Note a priority queue can be implemented in a
number of different ways - Heap (array/vector-based)
- Unsorted list, search for extreme element
- Sorted list, extreme element at first position
- STL set is possibility, as is ordered collection
91Priority Queue Generic Algorithms
- less ltTgt (T a, T b) returns true if a lt b
- greater ltTgt (T a, T b) returns true if a gt b
92Priority Queue Generic Algorithms - Heap
- make_heap() Takes an existing sequence of
elements and rearranges it to form a heap. - push_heap() Adds a new element to an existing
heap. - pop_heap() Removes the highest priority value
from a heap. - sort_heap() Takes a heap and turns it into a
sorted sequence.
93Priority Queue Applications
- Discrete-Event Simulation
- Huffman Coding (Data Compression)
- Scheduling Algorithms
94STL Container Comparison
- Need to look at several factors
- constraints on operations
- efficiency of important operations
- insert, remove, find
95BitSet
- Need to know certain underlying representations
for a given system - number of bits in byte
- number of bytes in integer types
- character code standard (e.g., ASCII, UNICODE)
- representation for integers
96BitSet
- STL class bitset
- include ltbitsetgt
- templateltsizegt
- set implemented efficiently at the bit level
- one bit indicates presence or absence of value
- implemented as vector of int
97BitSet
- bitwise AND
- bitwise OR
- bitwise XOR (exclusive OR)
- ltlt left shift (pad with zeros on right side)
- gtgt right shift (pad with 0 if unsigned
- pad with 0 if ve signed
- pad with 1 if ve signed)
- unary complement (toggle bits)
98BitSet
- / assume 16 bit int representation /
- int num1 5 / binary 0000000000000101 /
- int num2 -4 / binary 1111111111111100 /
- int num3
- num3 num1 / toggle 1111111111111010
/ - num3 num2 / toggle 0000000000000011 /
- num3 num1 num2/ AND 0000000000000100 /
- num3 num1 num2 / OR 1111111111111101 /
99BitSet
- num3 num1 num2 / XOR 1111111111111001 /
- int num2 3 / binary 0000000000000011
/ - num3 num2 ltlt 2 / lshift 0000000000001100
/ - num3 num2 gtgt 2 / rshift 0000000000000000
/
100Bitmaps
- Sets are used to represent the presence or
absence of properties and can also be used to
represent network information. - We would like to support a number of operations
on a set, including
101Bitmaps
- Initialize_Set // make the set empty
- Add (element) // add element to the set
- Remove (element) // remove element from the set
- Element_Of (element) // is element present in the
set? - Display_Set // display the contents of the set
- Union (set2) // elements in either the set or
set2 - Intersection (set2) // elements in both the set
set2 - Set_Difference (set2) // elements in set but not
in set2 - Is_Subset (set2) // is the set a subset of set2?
- Is_Empty( ) // is the set empty?
102Bitmap Implementation
- Several choices for implementation
- make an array of booleans, but each boolean could
take up a number of bits (could be a whole
integer, consisting of 8, 16, 32, or more bits on
some systems). Our set may also be 'sparse',
thereby wasting much space in the array. - Use a linked list of set elements this is much
more space efficient, and is often used. One
drawback is that we have the complexity and
overhead of pointers and their manipulation. - A third alternative is to use bit arrays, i.e.,
store set elements as bits.
103Bitmap Implementation
- Any integer-based data type in C (char, short,
int, long, unsigned int) can be viewed as a
collection of bits representing a value in the
specified type. - Each bit (right to left), represents a power of 2
(i.e. the first is 20 or 1, the second bit is 21
or 2, the third bit is 22 or 4, etc.) For
example - int value 5 // bit pattern 0000000000000101
- char ch_set 'A' // bit pattern 01000001
(ASCII 65) - int i_set 1026 // bit pattern 0000010000000010
104Bitmap Implementation
- Such variables can also be used to represent
sets. - Each position from the right normally represents
a power of 2 (1's place, 2's place, 4's place,
etc.) when used to represent the ASCII value of a
character or the actual value of an integer. - It can also be viewed as just representing the
presence or absence of a set element, with 1
representing presence and 0 representing absence.
- Thus, an 8-bit character could store the values
0-7 (normally viewed right to left, with the
right-most bit representing 0 and the left-most
bit representing 7), and a 16-bit integer could
represent the values 0-15 (again, right to left).
105Bitmap Implementation
- Assume a character representing a small set can
hold values 0 through 7. - How can we implement all of the desired
operations? - Remember that we have several bit operators in
C - , , , , ltlt , and gtgt
- Initialize_Set - Easy. An empty set has all bits
set to 0 - ? just initialize the set variable to 0
- ch_set 0 // or ch_set (char)0 implicit
type conversion 00000000 lt--- ch_set bit
pattern
106Bitmap Implementation
- Add - A general technique for a number of the
remaining operations is to apply some binary
bitwise operator to the set and a second bit
pattern called a mask. - The mask often involves setting one or more bits
in the 'correct' position(s). E.g., to add the
element 3 to the set, we could view this as -
- 00000000 lt--- old ch_set XOR with
- Å 00001000 lt--- mask
- 00001000 lt--- new ch_set
- To get mask char mask 1 //
00000001 - mask mask ltlt 3 // 00001000
107Bitmap Implementation
- So, our overall C fragment for adding 3 to the
set is - char mask 1 ltlt 3
- ch_set ch_set mask
- Generally, adding N to the set where N is a valid
element (here, 0 through 7) is done by - char mask 1 ltlt N
- ch_set ch_set mask // set 3 or
00001000 - Convince yourself on paper that this works with
non-empty sets as well by adding 5 to our set,
giving us the set 3, 5.
108Bitmap Implementation
- Remove - this is a little trickier.
- It looks like we could create a mask with a bit
at the position we want to remove and use
(bitwise XOR). This works if the element is
truly in the set. - E.g.,
- 00100100 // current ch_set 2,4
- Å 00000100 // mask item to be
removed - 00100000 // new ch_set 4
- but if we try removing an element that's not
present, we inadvertantly add the element we're
trying to remove! E.g., - 00100000 // current ch_set 4
- Å 00000100
- 00100100 // new ch_set 2,4
109Bitmap Implementation
- Right way
- - create a mask with the 1 in the correct
position - - toggle all bits in the mask
- - use (bitwise AND) mask with set.
- E.g., to remove 3 from 3,5, the mask is
- 00001000 ? 11110111 // toggled mask
- char mask 1 ltlt 3 // 00101000 3,5
- mask mask // 11110111 // toggled
mask - ch_set ch_set mask // 00100000 5
110Bitmap Implementation
- Element_Of
-
- To test if an element is in the set
- ? create a mask with a 1 bit in the correct
position - use to find the bitwise AND result,
- see if that result is non-zero.
- Shortcut ? return the (boolean) result of the
bitwise AND operation directly, with non-zero
representing 'true' and zero representing
'false'. E.g., given our two-element set above,
how can we test if 5 is in the set? - char mask (1 ltlt 5)
- char result ch_set mask // 00101000
(set) - // 00100000 (mask)
- // 00100000 return
(result)
111Bitmap Implementation
- Note that if the corresponding bit wasn't set in
ch_set, that bit won't be set in - the result, and we'd get a zero result. The
general membership function then - can be implemented concisely as
- return (ch_set (1 ltlt N))
112Some Examples
- include ltbitsetgt
- bitsetlt128gt bitsetA // set with 128 bits
- bitsetlt128gt bitsetB(100) // set with 100 bits
- bitsetlt128gt small(01101010) // set with 128
bits -
113BitSet Methods
- default, copy constructor
- flip, flip(index) // flip bit at index
- reset, reset(index)
- set, set(index)
- test(index)
- any(), none(), int count()
- (or), (and), (xor),
- ltlt, gtgt, to_string()
114BitSet Examples
- int main()
- bitsetlt126gt bset
- bset 4 // 0 0 0 0 0 1 0 0
- bset3 1 // 0 0 0 0 1 1 0 0
- if (bset.test(3))
- cout ltlt "bit position 3 is set" ltlt endl
- if (bset.any())
- cout ltlt "some bit position is set" ltlt endl
- if (bset.none()) cout ltlt "no bit position is
set" ltlt endl - for (int i 0 i lt MAX i)
- cout ltlt "b" ltlt i ltlt " " ltlt bseti ltlt
endl - return 0
- bit position 3 is set
- some bit position is set
- 0 0 1 1 0 0 0 0
-
115BitSet Examples
- bset.flip() // flip the entire set
- cout ltlt "Flipping entire set...."
- for (int i 0 i lt MAX i)
- cout ltlt bseti ltlt " " // print out
bitset - cout ltlt endl
-
- cout ltlt "Flipping only bit 3...."
- bset.flip(3) // flip only bit 3
- // print out bitset
-
- cout ltlt "Re-flipping only bit 3...."
- bset3.flip() // Re-flip bit 3
- // print out bitset
-
- 0 0 1 1 0 0 0 0
- Flipping entire set.... 1 1 0 0 1 1 1 1
- Flipping only bit 3.... 1 1 0 1 1 1 1 1
- Re-flipping only bit 3.... 1 1 0 0 1 1 1 1
116BitSet Applications
- System flags
- e.g., for output stream
- pos 1 may be fixed or exponential
- pos 2 may be showpoint
- pos 3-6 may be base
- etc.
117STL Container Comparison
118CS 265 - Data StructuresRecent Data Structures
119Recent Data Structures
- RTrees
- http//en.wikipedia.org/wiki/R-tree
- Google data structures
- http//www-db.stanford.edu/backrub/google.html