Рекурсивная сортировка слиянием в C ++

0

Я пытаюсь закодировать сортировку слияния в c++, но ее создание дает мне предупреждение о том, что она рекурсивна, и ее запуск приводит к переполнению стека. Я не понимаю, где я поступаю неправильно.

void mergesort(int thelist[]) {
  if (sizeof(thelist) <= 1)
    return;

  int middle = (sizeof(thelist) / 2);
  for (i = 0; i <= sizeof(thelist); i++){
    if (i < middle)
      lft[i] = thelist[i];
    else if (i >= middle)
      rght[i-middle] = thelist[i];
  }
  mergesort(lft);
  mergesort(rght);
  merge(lft, lft + 10, rght, rght + 10, sortedlist);
}
  • 10
    sizeof() не означает, что вы думаете, что это значит.
  • 2
    Почему в вашем коде закопано 10 ? Вам нужно передать длину последовательности. sizeof(theist) не делает то, что вы думаете. Ваше объявление mergsesort должно быть void mergesort(int thelist[], size_t len) а sizeof должно быть нигде в этой функции. Кроме того, я могу только представить себе , что вы используете глобалам для lft и rght , и я могу сказать вам сейчас это не будет делать то , что вы думаете , что это будет.
Показать ещё 2 комментария
Теги:
sorting
recursion
merge

3 ответа

1
Лучший ответ
  1. Если вы хотите обрабатывать разные части int [], вызывая одну и ту же функцию, попробуйте определить свою функцию как

    void mergesort(int thelist[], int start, int end)
    
  2. Что касается части sizeof(thelist), если вы хотите получить размер int []. Вы должны использовать

    sizeof(thelist)
    

    вместо

    sizeof(thelist)/sizeof(int)
    

    Пример:

    int a[] = {1, 2, 3, 4, 5};
    int n = sizeof(a)/sizeof(int); // n=5 now
    

PS: Вам также нужно дважды подумать над своей логикой кода и переписать ее. Основная функция должна выглядеть следующим образом:

void MergeSort(int data[], int start, int end)
{
    if (start < end)
    {
        int middle = (start+end)/2;

        // sort for first part
        MergeSort(data, start, middle);

        // sort for second part
        MergeSort(data, middle+1, end);

        // merge both parts together
        Merge(data, start, middle, end);
    }
}
  • 0
    к сожалению, в контексте функции sizeof thelist/sizeof int работать не будет. (в C, но я почти уверен в C ++ тоже)
  • 0
    @ShinTakezou Это должно работать в C ++. Смотрите пример (добавлено).
Показать ещё 6 комментариев
0
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void print_arr_data(std::vector<int>& arr, int start, int end) {
    cout << "start: " << start << " end: " << end << endl;
    int len = abs(end - start) + 1;
    for(auto it = arr.begin() + start; it != arr.begin() + start + len; ++it) {
        cout << *it << ",";
    }
    cout << endl;
}

void merge(std::vector<int>& arr, int start, int end) {
    int len = abs(start - end);
    std::sort(arr.begin() + start, arr.begin() + start + len);
}

void merge_sort(std::vector<int>& arr, int start, int end) {
    // check if the array is not a unit array, then dont divide anymore
    print_arr_data(arr, start, end);

    if (start < end) {
        int mid = (start + end)/2;

        merge_sort(arr, start, mid);
        merge_sort(arr, mid+1, end);
        merge(arr, start, end);
    }
}

int main() {
    std::vector<int> data = {4,1,2,3,7,8,5,6,9};
    merge_sort(data, 0, data.size()-1);

    cout << "*******" << endl;
    for (int i : data) {
        cout << i << endl;
    }
    cout << "*******";

    return 0;
}
0
#include <iostream>

using namespace std;

void merge(int *, int *, int, int, int);
void mergesort(int *a, int *b, int low, int high)
{
    int pivot;
    if (low < high)
    {
        pivot = (low + high)/2;
        mergesort(a, b, low, pivot);
        mergesort(a, b, pivot + 1, high);
        merge(a, b, low, pivot, high);
    }
}
void merge(int *a, int *b, int low, int pivot, int high)
{
    int h, i, j, k;
    h = low;
    i = low;
    j = pivot + 1;

    while ((h <= pivot) && (j <= high)) // Traverse both halves of the array
    {
        if (a[h] <= a[j]) // if an element of left half is less than element of right half
        {
            b[i] = a[h]; // store element of left half in the temporary array
            h++; // shift the index of the array from which the element was copied to temporary 
        }
        else // otherwise store the element of the right half in the temporary array
        {
            b[i] = a[j];
            j++; // shift the index of the array from which the element was copied to temporary 
        }
        i++;
    }
    if (h > pivot) // If traversal of left half is done, 
                   // copy remaining elements from right half to temporary
    {
        for (k = j; k <= high; k++)
        {
            b[i] = a[k];
            i++;
        }
    }
    else // otherwise copy remaining elements from left half to temporary
    {
        for (k = h; k <= pivot; k++)
        {
            b[i] = a[k];
            i++;
        }
    }
    for (k = low; k <= high; k++) a[k] = b[k]; // recopy the values from temporary to original array.
}

int main()
{
    int a[] = {12, 10, 43, 23, -78, 45, 123, 56, 98, 41, 90, 24};
    int num;

    num = sizeof(a)/sizeof(int);

    int b[num]; // temporary array to be used for merging

    mergesort(a, b, 0, num-1);

    for (int i = 0; i < num; i++)
        cout << a[i] << " ";
    cout << endl;
}
  • 0
    Вы должны добавить текст, объясняющий, о чем ваш код и почему он отвечает на вопрос.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню