какие способы сортировки можно выделить
мне нужны алгоритмы сортировки массивов
а по ним можно отсортировать и линейный список
сортировка производится путем изменения ссылок у элементов (next и prev)
Для массивов чаще используют quick sort, так как он имеет среднюю сложность O(n * log^2(n)) и не требует дополнительной памяти, но требует произвольного доступа к элементам, поэтому для списков он крайне неэффективен.
> а по ним можно отсортировать и линейный список
Для списков тебе нужен merge sort (вбей в google) — этот алгоритм не требует произвольного доступа к сортируемой последовательности (как, к примеру, quick sort) и поэтому идеально подходит для списков, но требует дополнительной памяти.
Вот написал в качастве разминки... Сложность n*log(n) надо памяти log(n) (как QuickSort'у) но данная реализация просто ваделяет памяти под список максимум из 2^32 элементов...(512 байт)
примечание: синтаксис языка С++(думаю на С перевести сможешь сам)
Для двусвязного списка алгоритм будет тотже самый НО придется сделать еще один проход для того чтобы сделать валидными указатели на предыдущие элементы.
Поддерживать список в валидном состоянии во время сортировки я посчитал не нужным. Ибо ничего кроме потери производительности это не даст.
А сортировочка получилась зверская. Соложность у нее O*N*log2(N). Причем на случайных последовательностях O чуть меньше 1, а на упорядочиных падает почти до 0.5 Что и ожидалось учитывая как я реализовал merge_list
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
WolfHound wrote:
> А сортировочка получилась зверская. Соложность у нее O*N*log2(N). Причем на случайных последовательностях O чуть меньше 1, а на упорядочиных падает почти до 0.5 Что и ожидалось учитывая как я реализовал merge_list
Что это за метод сортировки?
P.S. классический merge sort не чувствителен к характеру входной последовательности и его сложность всегда постоянна — O(n * log^2(n)).
Здравствуйте, boxter, Вы писали:
B>какие способы сортировки можно выделить B>мне нужны алгоритмы сортировки массивов B>а по ним можно отсортировать и линейный список B>сортировка производится путем изменения ссылок у элементов (next и prev)
Я имею в виду, что тебе нужно не рожать одну мега-функцию, а разбить её на детальки.
Например, выделить примитивные операции над списками (вставка/удаление элементов, склеивание/расщепление списков).
Здравствуйте, MaximE, Вы писали:
>> А сортировочка получилась зверская. Соложность у нее O*N*log2(N). Причем на случайных последовательностях O чуть меньше 1, а на упорядочиных падает почти до 0.5 Что и ожидалось учитывая как я реализовал merge_list
ME>Что это за метод сортировки?
Сам придумал.
Все просто merge_list сливает два отсортированных списка (список из одного элемента отсортирован ) причем когда один список закончился второй без лишних телодвжений приклеевается в конец ибо все оставшияся в нем элементы гарантированно не меньше (отсюда производительность и плавает к счастью только в лучшую сторону )
Основной алгоритм построен так чтобы всегда сливать списки одинаковой длинны(за исключением того момента когда у нас закончится исходный список но и тогда сливаются списки близкой длинны)
ME>P.S. классический merge sort не чувствителен к характеру входной последовательности и его сложность всегда постоянна — O(n * log^2(n)).
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Слега пооптимизировал... уменьшил колличество дополнительной памяти в 2 раза. Надеялся что еще и колличество обращений к памяти будет меньше но в x86'ой архитектуре маловато регистров... (хотя память действительно стал немного меньше дергать но всеже мог бы еще меньше)
Хотя все это мелочи и реально производительности скорее всего не добавилось.
Здравствуйте, WolfHound, Вы писали:
WH>Слега пооптимизировал... уменьшил колличество дополнительной памяти в 2 раза.
И внес маленький бажик... правда он не влиял на правильность сортировки и почти не влиял на скорость но всеравно не порядок...
В функции list_sort надо
int count = 0;
заменить на
int count = 1;
иначе в начале стека застревает список из одного элемента, а это добавляет O(N — 1) сложности при склеевании списков оставшихся после работы основного алгоритма.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Сортировка линейного списка
От:
Аноним
Дата:
15.12.04 11:59
Оценка:
Здравствуйте, WolfHound, Вы писали:
WH>примечание: синтаксис языка С++(думаю на С перевести сможешь сам)
Я затем и писал примечание, чтоб кто-то написал сразу по синтаксису С.
Поймите меня правильно: я еще новичек в это деле, и самому мне проблематично перевести с С++ на С (учитывая то, что я только изучаю С, а С++ будет только после нового года).
Если не очень сложно, попробуйте все таки написать на С (Буду очень благодарен).
А>Я затем и писал примечание, чтоб кто-то написал сразу по синтаксису С. А>Поймите меня правильно: я еще новичек в это деле, и самому мне проблематично перевести с С++ на С (учитывая то, что я только изучаю С, а С++ будет только после нового года). А>Если не очень сложно, попробуйте все таки написать на С (Буду очень благодарен).
Это вряд ли кому-нибудь из форума сложно, просто никто не хочет делать твое домашнее задание К тому же не сложное И не интересное
Кодт дал тебе дельный совет, в каком направлении двигаться для решения задачи, назвали подходящий алгоритм, что еще нужно?
Почему-бы не попробовать самому, а? А если в процессе собственного решения у тебя возникнут конкретные вопросы — я не сомневаюсь, что на них конкретно же ответят.
Думай, прежде чем родиться в этой сказочной стране!
(с) Антон Духовской
Здравствуйте, Аноним, Вы писали:
А>Если не очень сложно, попробуйте все таки написать на С (Буду очень благодарен).
Что значит "попробуйте"? А ты?
У задачи есть 3 составляющие:
1) структура данных
2) алгоритм
3) закодировать это на конкретном языке
Со структурой ты почти разобрался (двусвязный список).
Почти — потому что не определил над ней удобный инструментарий (в том числе — примитивные операции).
Например, часто двусвязный список удобно надстраивать специальным объектом "список в целом"
Операция "обмен элементов", сводящаяся к выдёргиванию-вставлению, ещё более громоздка (нужно установить значения 8 указателей). Поэтому вынесение её в отдельную процедуру — тем более пригодится.
Отчасти, алгоритм повлечёт разработку доп.структур. Например, представление подсписка как отдельной структуры (для некоторых рекурсивных алгоритмов).
Ну а роль языка (Си или С++) на этой задаче сводится к минимуму.
Возможно, тебе пригодятся указатели на указатели (см. структуры данных); а возможно, и нет.
Здравствуйте, MaximE, Вы писали:
ME>Для списков тебе нужен merge sort (вбей в google) — этот алгоритм не требует произвольного доступа к сортируемой последовательности (как, к примеру, quick sort) и поэтому идеально подходит для списков, но требует дополнительной памяти.