Случайный вывод с рекурсивной сортировкой слиянием С++

Я следовал этому рекурсивному алгоритму для сортировки слиянием, описанному в Википедии.

Вот код, который я придумал:

int* merge(int left[], int leftSize, int right[], int rightSize){
int result[leftSize + rightSize];   //The merged array
int resultPointer = 0;  //Index position of where to insert element
int leftPointer = 0;
int rightPointer = 0;

//While length of either of the lists is > 0
while((leftSize > 0) || (rightSize > 0)){

    cout << "Got here" << endl;
    //If length of both left and right lists is > 0
    if((leftSize > 0) && (rightSize > 0)){

        //Compare first elements from both lists and put smallest one in the result list
        if(left[0] < right[0]){
            result[resultPointer] = left[0];
            leftPointer++;
            leftSize--;
        }else if(right[0] < left[0]){
            result[resultPointer] = right[0];
            rightPointer++;
            rightSize--;
        }else{
            //if both elements are the same, put them both in the result list
            result[resultPointer] = left[0];
            leftPointer++;
            leftSize--;
            result[resultPointer++] = right[0];
            rightPointer++;
            rightSize--;
        }
        resultPointer++;    //Increment pointer to point to next empty element

    }else if(leftSize > 0){
        result[resultPointer] = left[0];
        leftPointer++;
        leftSize--;
    }else if(rightSize > 0){
        result[resultPointer] = right[0];
        rightPointer++;
        rightSize--;
    }


}

//int* resultList = result;

return result;
}

int* merge_sort(int list[], int size){

//If list has 1 element then it is sorted so just return that
if(size<=1){
    return list;
}

int middle = size/2;    //Get mid point of given list

//Create left and right arrays
int left[middle];
int right[size-middle];

for(int i = 0; i<size-middle; i++){

    if(i<middle){
        left[i] = list[i];
    }
    right[i] = list[i+middle];
}

//Recursively call merge sort to sort out the sublists
int* leftList = merge_sort(left, middle);
int* rightList = merge_sort(right, size-middle);

//Merge the sorted lists and return a fully sorted list

int* merged = merge(leftList, middle, rightList, size-middle);

return merged;
}

Полученный результат представляет собой просто набор случайных чисел (что, я думаю, происходит, когда что-то не было инициализировано). Эта реализация может быть глупой, но я все равно хотел бы знать, что здесь происходит не так.

Ваше здоровье


person freakii    schedule 18.08.2012    source источник


Ответы (3)


Вы возвращаете указатель из вашей функции слияния, который указывает на локальную переменную. Локальная переменная выйдет из области видимости в тот момент, когда вы вернетесь из функции слияния. Таким образом, вы возвращаете указатель, который не указывает ни на какую допустимую память.

person Eelke    schedule 18.08.2012
comment
Ах. Итак, как я могу это исправить? Сделав результат глобальной переменной? - person freakii; 18.08.2012
comment
Глобальные переменные — это всегда плохая идея. В этом случае я думаю, что было бы лучше передать третий буфер для слияния, который достаточно велик для хранения результата. - person Eelke; 18.08.2012
comment
Спасибо за Ваш ответ. Однако в итоге я просто использовал векторы, как показано на странице: en.wikibooks.org /wiki/Algorithm_Implementation/Сортировка/ - person freakii; 19.08.2012

Ваша функция слияния возвращает указатель на локальную переменную.

person Vaughn Cato    schedule 18.08.2012

У вас есть более чем простые проблемы с инициализацией:
При компиляции я получаю следующие ошибки:

> g++ -Wall -Wextra -pedantic merge.cpp  

merge.cpp: In function ‘int* merge(int*, int, int*, int)’:   
merge.cpp: 2: error: ISO C++ forbids variable-size array ‘result’  
merge.cpp:10: error: ‘cout’ was not declared in this scope  
merge.cpp:10: error: ‘endl’ was not declared in this scope  
merge.cpp: 2: warning: address of local variable ‘result’ returned  

merge.cpp: In function ‘int* merge_sort(int*, int)’:  
merge.cpp:62: error: ISO C++ forbids variable-size array ‘left’  
merge.cpp:63: error: ISO C++ forbids variable-size array ‘right’  

Из них я бы сказал:

merge.cpp: 2: warning: address of local variable ‘result’ returned  

Это критично. Но вы должны исправить их все.

person Martin York    schedule 18.08.2012
comment
Это странно, потому что я не получаю никаких других ошибок. - person freakii; 19.08.2012