Сортировка слиянием - C (СИ) (71185)
Формулировка задачи:
Восходящая сортировка слиянием массива. Метод слияния прямой.
Решение задачи: «Сортировка слиянием»
textual
Листинг программы
/* ANSI C 99 */
#include <stdio.h>
#include <string.h>
void merge(const int * srcA, size_t cntA, const int * srcB, size_t cntB, int * dst) {
while ( cntA ) {
if ( cntB ) {
if ( *srcA < *srcB ) {
*dst++ = *srcA++;
--cntA;
}
else if ( *srcA > *srcB ) {
*dst++ = *srcB++;
--cntB;
}
else {
*dst++ = *srcA++;
*dst++ = *srcB++;
--cntA;
--cntB;
}
}
else {
*dst++ = *srcA++;
--cntA;
}
}
while ( cntB ) {
*dst++ = *srcB++;
--cntB;
}
}
int * merge_sort(int * array, size_t count) {
if ( count > 1 ) {
int tmp[count];
merge(merge_sort(array, count / 2), count / 2, merge_sort(array + count / 2, count - count / 2), count - count / 2, tmp);
memcpy(array, tmp, sizeof(int) * count);
}
return array;
}
void dump(const int * array, size_t count) {
while ( count-- )
printf("%d%c", *array++, ( count ) ? ' ' : '\n');
}
#define elements_count(a) ( sizeof(a) / sizeof(*(a)) )
int main(void) {
int arr[] = { 3, 5, 2, 4, 2, 9, 1, 0, 6, 9, 0, 2 };
printf("Unsorted: ");
dump(arr, elements_count(arr));
printf("Sorted: ");
dump(merge_sort(arr, elements_count(arr)), elements_count(arr));
return 0;
}
Объяснение кода листинга программы
- В функции
mergeпроисходит сортировка слиянием массивовsrcAиsrcBв массивdst. - Если
cntAбольшеcntB, то значит массивsrcAбольше массиваsrcB, и есть возможность, что в процессе сортировки элементы массиваsrcBбудут перезаписаны. Поэтому в этой ветке сначала сортируются элементы массиваsrcA, а затем массиваsrcB. - Если
cntAменьшеcntB, то значит массивsrcAменьше массиваsrcB, и есть возможность, что в процессе сортировки элементы массиваsrcAбудут перезаписаны. Поэтому в этой ветке сначала сортируются элементы массиваsrcB, а затем массиваsrcA. - Если элементы
srcAиsrcBравны, то вdstзаписывается сначала элементsrcA, а затем элементsrcB. - Если
cntAбольшеcntB, то значит массивsrcAбольше массиваsrcB, и есть возможность, что в процессе сортировки элементы массиваsrcBбудут перезаписаны. Поэтому в этой ветке сначала сортируются элементы массиваsrcA, а затем массиваsrcB. - Если
cntAменьшеcntB, то значит массивsrcAменьше массиваsrcB, и есть возможность, что в процессе сортировки элементы массиваsrcAбудут перезаписаны. Поэтому в этой ветке сначала сортируются элементы массиваsrcB, а затем массиваsrcA. - Если элементы
srcAиsrcBравны, то вdstзаписывается сначала элементsrcA, а затем элементsrcB. - В функции
merge_sortпроисходит рекурсивная сортировка массиваarray. - Если
countбольше 1, то массивarrayразбивается на два массива, и каждый из них сортируется отдельно. - Затем сортированные массивы объединяются в один массив
tmp, и оригинальный массивarrayзаменяется отсортированным массивомtmp. - В функции
dumpпроисходит вывод элементов массива на экран. - Если
countбольше 0, то выводится следующий элемент массива и счетчикcountуменьшается на 1. - Если
countравен 0, то выводится символ новой строки\n. - В функции
mainсоздается массивarr, содержащий 14 элементов. - Выводится несортированный массив
arr. - Массив
arrсортируется с помощью функцииmerge_sort. - Выводится отсортированный массив
arr.