Реализации алгоритмов/Сортировка/Слиянием: различия между версиями

Содержимое удалено Содержимое добавлено
Нет описания правки
Строка 4:
 
/**
* @brief Сортировка элементов от lleft до rright массива buf
* @param[in/out] buf - сортируемый массив
* @param[in] lleft - левая граница. При первой итерации lleft = 0
* @param[in] rright - правая граница. При первой итерации rright = buf.size() - 1
*
* В результате сортируются все элементы массива buf от lleft до rright включительно.
*/
template<typename Type>
void MergeSort(vector<Type>& buf, size_t lleft, size_t rright)
{
//! Условие выхода из рекурсии
if(lleft >= rright) return;
 
size_t mmiddle = (lleft + r(right - left) / 2;
 
//! Рекурсивная сортировка полученных массивов
MergeSort(buf, lleft, mmiddle);
MergeSort(buf, mmiddle + 1, rright);
merge(buf, lleft, rright, mmiddle);
}
 
Строка 28:
* @brief Слияние элементов.
* @param[in/out] buf - массив
* @param[in] lleft - левая граница. При певой итерации lleft = 0
* @param[in] rright - правая граница. При первой итерации rright = buf.size() - 1
* @param[in] mmiddle - граница подмассивов.
*
* Массив buf содержит два отсортированных подмассива:
* - [lleft; mmiddle] - первый отсортированный подмассив.
* - [mmiddle+1; rright] - второй отсортированный подмассив.
* В результате получаем отсортированный массив, полученный из двух подмассивов,
* который сохраняется в buf[lleft; rright].
*/
template<typename Type>
static void merge(vector<Type>& buf, size_t lleft, size_t rright, size_t mmiddle)
{
if (lleft >= rright || mmiddle < lleft || mmiddle > rright) return;
if (rright == lleft + 1 && buf[lleft] > buf[rright]) {
swap(buf[lleft], buf[rright]);
return;
}
 
vector<Type> tmp(&buf[lleft], &buf[lleft] + (rright + 1));
 
for (size_t i = lleft, j = 0, k = mmiddle - lleft + 1; i <= rright; ++i) {
if (j > mmiddle - lleft) {
buf[i] = tmp[k++];
} else if(k > rright - lleft) {
buf[i] = tmp[j++];
} else {
Строка 70:
* m1 - Первый массив
* m2 - Второй массив
* l1len_1 - Длина первого массива
* l2len_2 - Длина второго массива
* Возвращает объединённый массив
*/
template <class T>
T* merge(T *m1, T* m2, int l1len_1, int l2len_2)
{
T* ret = new T[l1len_1+l2len_2];
int n = 0;
// Сливаем массивы, пока один не закончится
while (l1len_1 && l2len_2) {
if (*m1 < *m2) {
ret[n] = *m1;
m1++;
--l1len_1;
} else {
ret[n] = *m2;
++m2;
--l2len_2;
}
++n;
}
// Если закончился первый массив
if (l1len_1 == 0) {
for (int i = 0; i < l2len_2; ++i) {
ret[n++] = *m2++;
}
} else { // Если закончился второй массив
for (int i = 0; i < l1len_1; ++i) {
ret[n++] = *m1++;
}
Строка 109:
void mergeSort(T * mas, int len)
{
int n = 1, lk, ost;
T * mas1;
while (n < len) {
lk = 0;
while (lk < len) {
if (lk + n >= len) break;
ost = (lk + n * 2 > len) ? (len - (lk + n)) : n;
mas1 = merge(mas + lk, mas + lk + n, n, ost);
for (int i = 0; i < n + ost; ++i)
mas[lk+i] = mas1[i];//тут нужно что-то поменять, потому что это лишнее копирование, и оно увеличивает время работы алгоритма в два раза
delete [] mas1;
lk += n * 2;
}
n *= 2;
Строка 165:
 
template <typename Item>
void MergeSort(Item a[], int lleft, int rright)
{
int mmiddle;
 
// Условие выхода из рекурсии
if(lleft >= rright) return;
 
mmiddle = (lleft + r(right - left) / 2;
 
// Рекурсивная сортировка полученных массивов
MergeSort(a, lleft, mmiddle);
MergeSort(a, mmiddle + 1, rright);
Merge(a, lleft, rright, mmiddle);
}