1. About Set
C + + STL has been widely praised, but also by a lot of people use, not only to provide such as vector, String, list and other convenient containers, more importantly, the STL encapsulates many complex data structure algorithms and a large number of commonly used data structure operations. Vector package Array, list encapsulates the chain list, map and set encapsulated two fork tree, etc., in the encapsulation of these data structures, STL in accordance with the programmer's use habits, in the form of member functions to provide common operations, such as: Insert, sort, delete, find and so on. Let the user in the STL use process, and will not feel unfamiliar.
For set, the Set association container must be described. Set as a container is also used to store data types of the same data type, and can fetch data from a data collection, in which the values of each element are unique, and the system can automatically sort according to the value of the element. It should be noted that the values of the elements in the set cannot be changed directly. C + + STL Standard Association container set, Multiset, map, Multimap internal use is a very efficient balance search binary tree: Red-black tree, also become RB tree (Red-black). RB Tree has better statistical performance than general balanced binary tree, so the STL is chosen as the internal structure of the associated container.
There are several questions about set:
(1) Why is the insert deletion efficiency of map and set higher than in other sequence containers?
Most people say it's simple, because there's no need to do memory copy and memory movement for the associated container. That's right, that's true. All elements in the set container are stored as nodes, and their node structure is similar to the linked list, pointing to the parent node and child nodes. The structure diagram may be as follows:
A
/ \
B C
/ \ / \
D E F G
So when inserting only need to do a little transformation, the point of the node pointer to the new node on it. Delete the same time, slightly do the transformation after the pointer to the Delete node point to the other node is OK. Everything here is a pointer to swap, and the memory move does not matter.
(2) Why is the previously saved iterator not invalidated after each insert?
Iterator here is the pointer to the node, memory does not change, pointing to the memory of how the pointer will not be invalidated (of course, the deleted element itself has been invalidated). In contrast to vectors, each deletion and insertion of a pointer may fail, as is the call push_back at the end of the insert. Because in order to ensure the continuous storage of internal data, iterator points to the block within the deletion and insertion process may have been other memory coverage or memory has been released. Even when push_back, there may not be enough space inside the container, need a new larger memory, only to release the previous memory, apply for new and larger memory, copy the existing data elements to the new memory, and finally put the elements that need to be inserted to the last, then the previous memory pointers are naturally unavailable. When used in conjunction with find algorithms in particular, keep this principle in mind: do not use expired iterator.
(3) What is the change in the insertion and search speed of the set when the data element is increased?
If you know log2 's relationship, you should have a thorough understanding of the answer. Finding in set is using a binary lookup, that is, if you have 16 elements, you can find the result at a maximum of 4 times, with 32 elements, up to 5 times. So there are 10,000 of them? The maximum number of comparisons is log10000, up to 14 times, if it is 20,000 elements? Up to 15 times. See, when the amount of data increased by one times, the number of searches is only 1 times more than 1/14 of the search time. After you understand this, you can safely put elements into it.
The methods commonly used in 2.set
--------------------------------------------------------------------------------
Begin () returns the first element of the set container
End (), returns the last element of the set container
Clear (), delete all elements in the set container
Empty () to determine if the set container is empty
Max_size (), returns the maximum number of elements that the set container may contain
Size (), returns the number of elements in the current set container
Rbegin, the returned value and end () are the same
Rend (), the value returned is the same as Rbegin ()
Write a program to practice these simple steps:
Copy Code code as follows:
#include <iostream>
#include <set>
using namespace Std;
int Main ()
{
set<int> s;
S.insert (1);
S.insert (2);
S.insert (3);
S.insert (1); The size value of the
cout<< set is: "<<s.size () <<endl; The maxsize value for the
cout<< set is: "<<s.max_size () <<endl; The first element in the
cout<< set is: "<<*s.begin () <<endl; The last element in the
cout<< set is: "<<*s.end () <<endl;
s.clear ();
if (S.empty ())
{
cout << "Set is EMPTY!!! "<<endl;
} The size value of the
cout<< set is: "<<s.size () <<endl; The maxsize value for the
cout<< set is: "<<s.max_size () <<endl;
return 0;
}
Run Result:
Summary: Although inserting a 1 after inserting 3, we found that the last value in set is still 3 ha, which is set. Also note that the Begin () and end () functions do not check whether the set is empty, and it is best to use empty () before use to verify that the set is empty.
--------------------------------------------------------------------------------
Count () is used to find the number of times a key value in a set appears. This function is not very useful in set because a key value can only occur 0 or 1 times in a set, which becomes a way to determine if a key value has appeared in set.
Sample code:
Copy Code code as follows:
#include <iostream>
#include <set>
using namespace Std;
int main ()
{
Set<int> s;
S.insert (1);
S.insert (2);
S.insert (3);
S.insert (1);
The number of occurrences of 1 in cout<< "set is:" <<s.count (1) <<endl;
The number of occurrences of 4 in cout<< "set is:" <<s.count (4) <<endl;
return 0;
}
Run Result:
Equal_range () returns a pair of locators that represent the first element that is greater than or equal to the given key value and the first element greater than the given key value, which is a pair type, and is equal to the value of end () if which fails in the pair of locators. What is the use of this specific I have not met ~ ~ ~
Sample code:
Copy Code code as follows:
#include <iostream>
#include <set>
using namespace Std;
int main ()
{
Set<int> s;
Set<int>::iterator ITER;
for (int i = 1; I <= 5; ++i)
{
S.insert (i);
}
for (iter = S.begin (); Iter!= s.end (); ++iter)
{
cout<<*iter<< "";
}
cout<<endl;
Pair<set<int>::const_iterator,set<int>::const_iterator> PR;
PR = S.equal_range (3);
cout<< "The first number greater than or equal to 3 is:" <<*pr.first<<endl;
cout<< "The first number greater than 3 is:" <<*pr.second<<endl;
return 0;
}
Run Result:
Erase (iterator), delete the value that the locator iterator points to
Erase (first,second), delete the value between the locator's A and the second
Erase (key_value), delete the value key_value the key value
Look at the program:
Copy Code code as follows:
#include <iostream>
#include <set>
using namespace Std;
int main ()
{
Set<int> s;
Set<int>::const_iterator ITER;
Set<int>::iterator;
Set<int>::iterator second;
for (int i = 1; I <= ++i)
{
S.insert (i);
}
The first type of deletion
S.erase (S.begin ());
The second type of deletion
i = S.begin ();
Second = S.begin ();
second++;
second++;
S.erase (First,second);
The third type of deletion
S.erase (8);
cout<< "deleted after the set element is:";
for (iter = S.begin (); Iter!= s.end (); ++iter)
{
cout<<*iter<< "";
}
cout<<endl;
return 0;
}
Run Result:
Summary:The delete operation in set is not to do any error checking, such as the legality of the locator, etc., so use the time you must pay attention to.
--------------------------------------------------------------------------------
Find (), returns the value of the specified locator, and returns end () if it is not found.
Sample code:
Copy Code code as follows:
#include <iostream>
#include <set>
using namespace Std;
int main ()
{
int a[] = {1,2,3};
set<int> s (a,a+3);
Set<int>::iterator ITER;
if (iter = S.find (2))!= S.end ())
{
cout<<*iter<<endl;
}
return 0;
}
Insert (Key_value); Inserts a key_value into the set, and the return value is Pair<set<int>::iterator,bool>,bool marks the success of the insertion, while the iterator represents the insertion position, if Key_ Value is already in set, the position of the key_value represented by iterator in set.
Inset (First,second); Inserts the element between the locator one and second into the set, and the return value is void.
Sample code:
Copy Code code as follows:
#include <iostream>
#include <set>
using namespace std;
int Main ()
{
int a[] = {1,2,3};
set<int> S;
Set<int>::iterator iter;
S.insert (a,a+3);
for (iter = S.begin (); Iter!= s.end (); ++iter)
{
& nbsp; cout<<*iter<< "";
}
cout<<endl;
pair<set<int>::iterator,bool> PR;
PR = s.insert (5);
if (pr.second)
{
cout <<*pr.first<<endl;
}
return 0;
}
Run Result:
Lower_bound (Key_value), returns the first locator greater than or equal to Key_value
Upper_bound (Key_value), returns the last locator that is greater than or equal to Key_value
Sample code:
Copy Code code as follows:
#include <iostream>
#include <set>
using namespace Std;
int main ()
{
Set<int> s;
S.insert (1);
S.insert (3);
S.insert (4);
Cout<<*s.lower_bound (2) <<endl;
Cout<<*s.lower_bound (3) <<endl;
Cout<<*s.upper_bound (3) <<endl;
return 0;
}
Run Result: