Можно ли выполнить слияние на месте без временного хранилища?

Я просто подумал, если бы я реализовал 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)

Для меня это означает, что известные эффективные версии алгоритма требуют дополнительного хранилища. Я правильно читаю? Если да, то есть ли упоминание о том, откуда должно поступать хранилище?

12
задан Evan Teran 7 December 2010 в 19:22
поделиться