在快排的基础上进行算法实现,只是每次分区之后只选择第i大的元素所在的区域进行查找。平均算法复杂度为O(n),最差算法复杂度为O(n^2),如同快排一样,出现最差情况的概率极低。 #ifndef RANDOMSELECT_H #define RANDOMSELECT_H #include <iostream> /** * @brief Exception class which means that i is larger than the number of elements in the array */ class OutOfRange { public: OutOfRange(){} OutOfRange(std::string mes); OutOfRange(OutOfRange &a); ~OutOfRange(){} std::string Message() const; private: std::string message; }; OutOfRange::OutOfRange(std::string mes): message(mes) { } OutOfRange::OutOfRange(OutOfRange &a) { message = a.Message(); } std::string OutOfRange::Message() const { return message; } /** * @brief Partition the array * * @tparam T: template type * @param array: the array to be partitioned * @param start: the start position of the array * @param end: the index of the last element in the array * * @return The partition position */ template <typename T> int Partition(T *array, int start, int end) { T x = array[end]; int i = start; int j = end - 1; //i is to find the element who is larger than array[end] //j is to find the element who is smaller than array[end] while (i <= j) { if (array[i] <= x) { ++i; } else { while (i <= j) { if (array[j] > x) { --j; } else { //swap element at i and j T temp = array[i]; array[i++] = array[j]; array[j--] = temp; break; } } } } //i will be the first element who is larger than array[end] after arrange the array //if there is no element larger than array[end], i will point to array[end] T temp = array[i]; array[i] = x; array[end] = temp; return i; } /** * @brief Get the i'th element in the array. The badest complexity is O(n^2), the average complexity is O(n). * * @tparam V: template type * @param array: the array to be searched * @param start: the start position of the array * @param end: the index of the last element in the array * @param i: find the i'th element * * @return the i'th element */ template <typename V> V RandomSelect(V *array, int start, int end, int i) { if (i + start > end + 1) { OutOfRange a("ERROE: i is larger than the number of elements in the array!"); throw a; } if (start == end) { return array[start]; } int p = Partition(array, start, end); //k means the order of p in the array int k = p + 1 - start; if (i == k) { return array[p]; } if (i < k) { return RandomSelect(array, start, p - 1, i); } else { return RandomSelect(array, p + 1, end, i - k); } } #endif /* end of include guard: RANDOMSELECT_H */