2014-01-20 3 views
1

Есть ли какой-либо возможный способ сортировки всех видов данных в естественном смысле с помощью одной функции в C++? В моем случае я определяю структуры связанных списков, которые основаны на типе данных шаблона, и я хотел бы сортировать этот связанный список независимо от того, что он включает в качестве данных.Как написать общую функцию сортировки в C++?

+9

Ahem ['std :: sort'] (http://en.cppreference.com/w/cpp/algorithm/sort)? – Borgleader

+0

@Borgleader - плакат говорит, что у него есть связанный список, который не будет работать с 'std :: sort', поскольку он вряд ли будет структурой произвольного доступа. – Sean

+0

@Sean Вы пропустили точку. Вопрос: «Возможно ли это». Да смотрите std :: sort. – Borgleader

ответ

-1

Да, вы можете реализовать сортировку вставки, естественно, со связанным списком. Вы можете написать шаблонную функцию с аналогичным интерфейсом, как std::sort.

Вы можете использовать operator< для сравнения любых элементов или функции Compare.

Вы можете разрешить свой список в качестве ввода и вернуть отсортированный список в качестве вывода.

Сложность упадет до O(n^2) со вставкой сортировки, но это самый простой способ ИМО. И я не думаю, что вы можете сделать лучше с помощью контейнера с произвольным доступом. Возможно, сортировка merge может быть реализована для списка. Похоже, хороший кандидат.

Альтернативно вы можете копировать/перемещать свой список в структуру, которая поддерживает итераторы с произвольным доступом, сортировать ее с помощью std::sort и преобразовывать ее обратно в список. Это технически было бы сложнее, но довольно большие постоянные факторы из-за двух операций преобразования. Но для больших списков это было бы быстрее в конце.

+0

Вы действительно не должны заботиться о копиях или ходах, но «своп». Это также означает 'std :: sort'. – pmr

+0

Когда вы вычисляете чистую вычислительную сложность, да, конечно. Когда вы используете структуру данных для сортировки небольших наборов (я знаю, вы можете сказать, что меня не интересуют небольшие наборы данных, потому что они быстрые по определению), стоит помнить, что копирование материала также требует времени. И 'swap' - это копия или движение в любом случае, не так ли? Также я думаю, что в плохо спроектированном алгоритме (вроде моего грубого эскиза здесь) вы будете связаны памятью, а количество свопов может стать менее доминирующей операцией. Я видел несколько примеров, которые предполагали, что «malloc» - хорошая операция O (1) и сломал их сложность. – luk32

+0

Я не пытался сказать, что копии или ходы не имеют значения для производительности, но этот своп обобщает построение копии/перемещение конструкции. Если у вас есть хорошее определение (в математическом смысле) «swap», ваши алгоритмы более низкого уровня не должны заботиться о базовом механизме. – pmr

1

Есть несколько измерений к тому, что вы могли бы означать, общее:

  1. родовое по отношению к данным
  2. родовое по отношению к контейнеру

Первый самый простой для решения , Нам нужно подумать о том, какая сортировка требует работы: strict weak ordering наших данных. Теперь мы знаем природу функции, которую нам нужно предоставить нашему алгоритму сортировки, и нам нужен способ передать функцию. В C++ стало нормой считать, что operator< реализует такой порядок или передает Functor алгоритму, который его реализует. Таким образом, подпись стала бы:

template<typename T, typename Comp = std::less<T>> 
my_sort(my_list<T>& l, Comp c = Comp()); 

Существует еще одна операция, которую наш алгоритм сортировки обязательно выполнит: замена элементов. Поскольку мы находимся в нашем собственном маленьком мире, мы можем просто предположить, что все наши типы имеют функцию-член T::swap(T& rhs), которая выполняет именно это. В реальном мире мы будем использовать свободную функцию std::swap (с неквалифицированным вызовом и директивой по использованию, но это неясная техничность).

Вторая проблема намного сложнее, и вы на самом деле не хотите ее решать, поскольку вы хотите, чтобы ваш алгоритм сортировки работал над реализацией вашего списка. Я рекомендую вам погрузиться в std::sort и его требование понять, почему он был реализован таким образом и почему он не работает для std::list.

+2

Обратите внимание, что для списка может быть лучше исправить внутренний указатель списка без обмена данными (что может не подменять). – Jarod42

Смежные вопросы