Получение ошибки при сортировке слиянием. Может кто-нибудь помочь мне найти ошибку?

#c #algorithm #sorting #mergesort

#c #алгоритм #сортировка #сортировка слиянием

Вопрос:

Я пытаюсь выполнить сортировку слиянием более ПРОСТЫМ СПОСОБОМ, но не получаю желаемого результата. Он показывает мне, что какой-то цикл повторяется бесконечно. Кто-нибудь поможет мне найти, где ошибка в коде?

 #include <bits/stdc  .h>

void merge(int arr[], int, int, int);
void mergesort(int arr[], int, int);

using namespace std;

int main() {
    int n, m;
    cin >> n;
    int arr[n]; 
    for (int i = 0; i < n; i  )
        cin >> arr[i];
    mergesort(arr, 0, n);
    for (int i = 0; i < n; i  )
        cout << arr[i] << " ";
}

void merge(int arr[], int l, int mid, int h) {
    int i = l, j = mid, k = 0;
    int brr[h - l];

    while (i < mid amp;amp; j < h) {
        if (arr[i] <= arr[j])
            brr[k  ] = arr[i  ];
        else
            brr[k  ] = arr[j  ];
    }
    for(; i < mid; i  )
        brr[k  ] = arr[i];
    for(; j < h; j  )
        brr[k  ] = arr[j];
    
    int i = 0;
    for(k = l; k < h; k  )
        arr[k] = brr[i  ];
}

void mergesort(int arr[], int l, int h) {
    if (l < h) {
        int mid = l   (h - l) / 2;
        mergesort(arr, l, mid);
        mergesort(arr, mid, h);
        merge(arr, l, mid, h);
    }
}
  

Комментарии:

1. Что именно «это» показывает вам? Пожалуйста, опубликуйте полный вывод

2. Он показывает mergesort.exe перестал работать, когда я использую инструмент отладки, я обнаруживаю, что функция сортировки слиянием выполняется бесконечно,

3. Сделайте это if(l 1 < h) или, возможно, более четко, if (h - l > 1) . Вы продолжаете сортировать одноэлементные подпоследовательности бесконечно.

4. Вы будете рады услышать, что вам не нужна ничья помощь, чтобы разобраться в этом, просто инструмент, который у вас уже есть: ваш отладчик! Это именно то, для чего нужен отладчик. Он запускает вашу программу по одной строке за раз и показывает вам, что происходит. Знание того, как использовать отладчик, является необходимым навыком для каждого разработчика C , без исключений. С помощью вашего отладчика вы сможете быстро найти все ошибки в этой и всех будущих программах, которые вы пишете, не обращаясь ни к кому за помощью. Вы уже пробовали использовать свой отладчик? Если нет, то почему бы и нет? Что вам показал ваш отладчик?

5. Спасибо @IgorTandetnik создание if(l 1

Ответ №1:

Алгоритм верен, за исключением теста в mergesort : if (l < h) должно быть if (h - l >= 2)

Тест l < h используется в when h является индексом последнего элемента в срезе. В C и C гораздо проще и более идиоматично считать h исключенную верхнюю границу. Следовательно, минимальный фрагмент для разделения mergesort должен иметь длину не менее 2 : h - l >= 2 .

Обратите внимание, что выделение массивов как VLA рискованно для больших массивов: это может вызвать переполнение стека. C не поддерживает VLA (массивы переменной длины, т. Е. Автоматические массивы, Размер которых не является выражением времени компиляции), ваш компилятор поддерживает их как расширение.

Обратите также внимание, что последний for цикл в merge можно опустить, поскольку элементы, которые он копирует, уже находятся в правильном положении.

Вот модифицированная версия:

 #include <bits/stdc  .h>

void merge(int arr[], int, int, int);
void mergesort(int arr[], int, int);

using namespace std;

int main() {
    int n, m;
    cin >> n;
    int arr[n]; 
    for (int i = 0; i < n; i  )
        cin >> arr[i];
    mergesort(arr, 0, n);
    for (int i = 0; i < n; i  )
        cout << arr[i] << " ";
    cout << endl;
    return 0;
}

void merge(int arr[], int l, int mid, int h) {
    int i = l, j = mid, k = 0;
    int brr[h - l];

    while (i < mid amp;amp; j < h) {
        if (arr[i] <= arr[j])
            brr[k  ] = arr[i  ];
        else
            brr[k  ] = arr[j  ];
    }
    for(; i < mid; i  )
        brr[k  ] = arr[i];
    
    for(i = 0, k = l; k < j; k  , i  )
        arr[k] = brr[i];
}

void mergesort(int arr[], int l, int h) {
    if (h - l >= 2) {
        int mid = l   (h - l) / 2;
        mergesort(arr, l, mid);
        mergesort(arr, mid, h);
        merge(arr, l, mid, h);
    }
}