kth_order_statistic.hxx
Go to the documentation of this file.
1 /*===========================================================================================================
2  *
3  * HUC - Hurna Core
4  *
5  * Copyright (c) Michael Jeulin-Lagarrigue
6  *
7  * Licensed under the MIT License, you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * https://github.com/Hurna/Hurna-Core/blob/master/LICENSE
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License is
13  * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and limitations under the License.
15  *
16  * The above copyright notice and this permission notice shall be included in all copies or
17  * substantial portions of the Software.
18  *
19  *=========================================================================================================*/
20 #ifndef MODULE_SEARCH_MAX_KTH_ELEMENT_HXX
21 #define MODULE_SEARCH_MAX_KTH_ELEMENT_HXX
22 
23 #include <Sort/partition.hxx>
24 
25 // STD includes
26 #include <iterator>
27 
28 namespace huc
29 {
30  namespace search
31  {
47  template <typename IT, typename Compare = std::less_equal<typename std::iterator_traits<IT>::value_type>>
48  IT KthOrderStatistic(const IT& begin, const IT& end, unsigned int k)
49  {
50  // Sequence does not contain enough elements: Could not find the k'th one.
51  const auto kSize = static_cast<const int>(std::distance(begin, end));
52  if (k >= static_cast<unsigned int>(kSize))
53  return end;
54 
55  auto pivot = begin + (rand() % kSize); // Take random pivot
56  auto newPivot = sort::Partition<IT, Compare>(begin, pivot, end); // Partition
57 
58  // Get the index of the pivot (i'th value)
59  const auto kPivotIndex = std::distance(begin, newPivot);
60 
61  // If at the k'th position: found!
62  if (kPivotIndex == k)
63  return newPivot;
64 
65  // Recurse search on left part if there is more than k elements within the left sequence
66  // Recurse search on right otherwise
67  return (kPivotIndex > k) ? KthOrderStatistic<IT, Compare>(begin, newPivot, k)
68  : KthOrderStatistic<IT, Compare>(newPivot, end, k - kPivotIndex);
69 
70  }
71  }
72 }
73 
74 #endif // MODULE_SEARCH_MAX_KTH_ELEMENT_HXX
IT KthOrderStatistic(const IT &begin, const IT &end, unsigned int k)