Я просто подумал, если бы я реализовал std :: inplace_merge
, это, вероятно, выглядело бы примерно так:
template <class Bi, class Cmp>
void inplace_merge(Bi first, Bi middle, Bi last, Cmp cmp) {
if(first != last) {
typedef typename iterator_traits<Bi>::value_type T;
typedef typename iterator_traits<Bi>::difference_type Dist;
const Dist count = distance(first, last);
if(count != 1) {
// can I avoid this allocation?
T *const temp = new T[count];
merge(first, middle, middle, last, temp, cmp);
copy(temp, temp + count, first);
delete [] temp;
}
}
}
Я знаю, что мог бы просто использовать существующую реализацию, но это не совсем так. Мне было просто любопытно, есть ли алгоритм лучше, чем то, о котором я знаю.
Причина, по которой это пришло в голову, заключается в том, что большая часть стандартной библиотеки C ++ (вся STL, если я правильно помню) позволяет пользователю указать, как и где выполнять распределения, но если std :: inplace_merge
требует выделения по дизайну, кажется, что есть нет способа контролировать это, если это проблема.
Я думаю, намек на ответ исходит из самого стандарта относительно сложности std :: inplace_merge
:
Сложность:Когда достаточно дополнительных память имеется, (последняя - первая) - 1 сравнения. Если нет дополнительной памяти доступен алгоритм с сложность N log N (где N равно to last -first)
Для меня это означает, что известные эффективные версии алгоритма требуют дополнительного хранилища. Я правильно читаю? Если да, то есть ли упоминание о том, откуда должно поступать хранилище?