Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 这个合并排序算法的实现有什么问题吗?_C++_Arrays_Algorithm_Mergesort - Fatal编程技术网

C++ 这个合并排序算法的实现有什么问题吗?

C++ 这个合并排序算法的实现有什么问题吗?,c++,arrays,algorithm,mergesort,C++,Arrays,Algorithm,Mergesort,我知道有许多合并排序算法的实现。我已经根据CLRS算法简介一书中提供的算法实现了以下代码 void merge_sort(int arr[], int starting_index, int ending_index) { if(starting_index < ending_index) { int middle_index = (starting_index + ending_index)/2; merge_sort(a

我知道有许多合并排序算法的实现。我已经根据CLRS算法简介一书中提供的算法实现了以下代码

void merge_sort(int arr[], int starting_index, int ending_index) {  

    if(starting_index < ending_index) {         

        int middle_index = (starting_index + ending_index)/2;
        merge_sort(arr, starting_index, middle_index);  
        merge_sort(arr, middle_index+1, ending_index);
        merge_the_parts(arr, starting_index, middle_index, ending_index);   
    }
}

void merge_the_parts(int arr[], int starting_index, int middle_index, int ending_index) {

    int length_of_first_array = middle_index - starting_index + 1;
    int length_of_second_array = ending_index - middle_index;

    const int sentinel = INT_MAX;

    int left_arr[length_of_first_array + 1]; 
    int right_arr[length_of_second_array + 1]; 

    for(int i=0; i<length_of_first_array; i++) {
        left_arr[i] = arr[starting_index + i];      
    }

    // building second auxilliary
    for(int i=0; i<length_of_second_array; i++) {
        right_arr[i] = arr[(middle_index+1) + i];
    }

    left_arr[length_of_first_array] = sentinel; // use the sentinel as a condition
    right_arr[length_of_second_array] = sentinel;

    int i=0;
    int j=0;

    // the main merging loop
    for(int k=starting_index; k<ending_index+1; k++) {

        if(left_arr[i] <= right_arr[j]) {
            arr[k] = left_arr[i];
            i++;
        }

        else {
            arr[k] = right_arr[j];
            j++;
        }
    }   
}

void merge_sort(int arr[],int start_index,int end_index){
如果(开始索引<结束索引){
中间指数=(起始指数+结束指数)/2;
合并排序(arr、起始索引、中间索引);
合并排序(arr,中间索引+1,结束索引);
合并各部分(arr、起始索引、中间索引、结束索引);
}
}
无效合并部分(int arr[],int起始索引,int中间索引,int结束索引){
第一个数组的整数长度=中间索引-起始索引+1;
第二个数组的整数长度=结束索引-中间索引;
const int sentinel=int_MAX;
int left_arr[第一个数组的长度+1];
int right_arr[第二个数组的长度+1];

对于(int i=0;i您得到了错误的答案,因为考虑到问题中给出的范围,您只使用了
长的
来保存如此大的
计数值

# include <iostream>
# include <climits>
using namespace std;

long int merge(int *arr, int l, int mid, int r) {

    int n1 = mid - l + 1;
    int n2 = r - mid;

    int *arrL = new int[n1 + 1];
    int *arrR = new int[n2 + 1];

    for(int i=0; i<n1; i++) {
        arrL[i] = arr[l + i];
    }

    for(int j=0; j<n2; j++) {
        arrR[j] = arr[(mid + 1) + j];
    }

    arrL[n1] = INT_MAX;
    arrR[n2] = INT_MAX;

    int i = 0, j = 0;
    long int count = 0;

    for(int k=l; k<=r; k++) {

        if(arrL[i] < arrR[j]) {
            arr[k] = arrL[i];
            if(arrR[j] != INT_MAX) {
                count += (arrL[i] * (n2 - j));
            }
            i++;
        } else {
            arr[k] = arrR[j];
            j++;
        }
    }

    delete[] arrL;
    delete[] arrR;

    return count;
}

long int countSeries(int *arr, int l, int r) {

    long int count = 0;

    if(l < r) {

        int mid = (l + r) / 2;
        count += countSeries(arr, l, mid);
        count += countSeries(arr, mid + 1, r);
        count += merge(arr, l, mid, r);
        return count;
    }

    return count;
}

使用
long-long
可以保存较大的值且不会溢出:

长计数=0;
long-long-countSeries(int*arr,int-l,int-r){
,,
count+=(长-长)arrL[i]*(n2-j);


您自己回答了问题,出现了一个问题。请阅读,以帮助您编写更多有用的问题。此外,请提取并提供一个,其中包含足够的信息以再现故障。代码可以更改为检查索引是否到达子数组的末尾,而不是依赖sentinel(INT_MAX)值。如果数据不能包含sentinel值,这不是问题。可以通过一次性分配工作数组,并根据递归级别更改合并方向(或切换到自底向上的合并排序,并根据循环计数更改合并方向)来加快代码的速度。