Assuming the following snippet of code
set<int>::iterator it = st.begin();
it++;
What's the order of it++
. Does it take O(log n)?
# | User | Rating |
---|---|---|
1 | tourist | 3985 |
2 | jiangly | 3814 |
3 | jqdai0815 | 3682 |
4 | Benq | 3529 |
5 | orzdevinwang | 3526 |
6 | ksun48 | 3517 |
7 | Radewoosh | 3410 |
8 | hos.lyric | 3399 |
9 | ecnerwala | 3392 |
9 | Um_nik | 3392 |
# | User | Contrib. |
---|---|---|
1 | cry | 169 |
2 | maomao90 | 162 |
2 | Um_nik | 162 |
4 | atcoder_official | 161 |
5 | djm03178 | 158 |
6 | -is-this-fft- | 157 |
7 | adamant | 155 |
8 | awoo | 154 |
8 | Dominater069 | 154 |
10 | luogu_official | 150 |
Assuming the following snippet of code
set<int>::iterator it = st.begin();
it++;
What's the order of it++
. Does it take O(log n)?
Name |
---|
Yes.
It's O(1) amortized, as it just traverses binary tree going up and down, and O(log n) in a worst case for one ++ operation, as std::set uses red-black tree which has logarithmic height.
Very helpful. Thanks
Code from the post is
Beginning of the set is the leftmost element, and it's parent will be the next, so this code will always run in O(1). Am I right?
No, you're wrong.
First, the leftmost element isn't always a leaf, so the increment won't always work in O(1).
Second, I'm not sure that
set::begin()
must work in O(1) according to the C++ standard. So, I'd always rely only on the upper bound.Oh, I see now, thanks
It seems that if
begin()
is not a leaf then depth of its subtree is constant because black height of left subtree is 0, so black height of right subtree is 0 too. And it's either empty or one red vertex.Note, that I suppose that it's red-black tree and it's not guaranteed.
cppreference and cpkuspkus com say that std::set::begin() is constant but I'm not sure if it is reliable source
In C++11 23.2.1 "General container requirements", in Table 96 you have
In other words, iterating over the whole set takes
O(n)
worst case (inorder traversal). Executing a singleit++
(looking for successor) takesO(lg n)
worst case.