合并排序不适用于某些数字列表

时间:2019-02-18 02:24:16

标签: c++ mergesort

它可以与第二个数字列表一起正常使用,但不能与第一个数字列表一起使用,为什么?我该怎么做才能纠正它?我可以做些什么来解决这个问题?我已经学到了这一点,现在我意识到这是不完全正确的...

list_of_tuples.sort(key=len)
print(list_of_tuples)

第一个数组产生#include <iostream> using namespace std; void merge(int arr[], int start, int len) { int size = (len - start) + 1; int* b = new int[size](); int i = start; int mid = (start + len) / 2; int k = 0; int j = mid + 1; while (k < size) { if ((i <= mid) && (arr[i] < arr[j])) { b[k++] = arr[i++]; } else { b[k++] = arr[j++]; } } for (k = 0; k < size; k++) { arr[start + k] = b[k]; } delete[] b; } void mergeSort(int data[], int start, int end) { if (start < end) { int mid = (start + end) / 2; mergeSort(data, start, mid); mergeSort(data, mid + 1, end); merge(data, start, end); } } void printArray(int arr[], int size) { cout << "--------------------------------------------------------" << endl; cout << "Printing ordered array of integers after merge sort" << endl; for (int i = 0; i < size; i++) { cout << arr[i] << endl; } } int main() { int data[10] = { 2, 4, 3, 1, 7, 9, 8, 6, 5, 10 }; mergeSort(data, 0, 9); printArray(data, 10); //Merge Sort and Merge cout << "Calling Merge and Merge Sort Recursive Functions\n" "with array of 10 integers" << endl; int arrayOfInts[10] = { 10, 23, 34, 2, 56, 42, 78, 4, 84, 99 }; mergeSort(arrayOfInts, 0, 9); printArray(arrayOfInts, 10); system("pause"); } ,第二个数组产生排序的数组。

2 个答案:

答案 0 :(得分:2)

错误在这里:

if ((i <= mid) && (arr[i] < arr[j]))

您需要确保i<=mid ,而j<=len 。如果ij超出范围,则进行比较是未定义的行为,但是进行比较也没有用。

一旦获得一个超出范围的值,则从另一侧复制值。

// Copy and compare while both i and j are in range.
while (i <= mid && j <= len) {
    if (arr[i] < arr[j]) {
        b[k++] = arr[i++];
    }
    else {
        b[k++] = arr[j++];
    }
}
// Copy remaining from fist range (could be zero)
while(i <= mid) {
    b[k++] = arr[i++];
}
// Copy remaining from second range (could be zero)
while(j <= len) {
    b[k++] = arr[j++];
}

现在,代码已修复。您需要解决几个最佳实践问题。但是为此,您应该将代码带到Code Review

答案 1 :(得分:1)

您的merge()函数执行不正确,因此在最后一行的mergesort()中未使用适当的参数调用该函数,应在其中使用以下命令调用该函数:merge(data, start, mid, end);

查看Wikipedia,仅对该算法有一个一般的了解,就可以对其进行一些重写,这样我们就可以做到:

void mergeSort(int data[], int start, int end) {
    if (start < end) {
        int mid = (start + end) / 2;
        mergeSort(data, start, mid);
        mergeSort(data, mid + 1, end);
        merge(data, start, mid, end); // Changed this line to include the mid.
    }
}

然后重写merge()函数本身,使其符合新的参数要求,如下所示:

void merge(int arr[], int start, int mid, int len) {
  int i, j, k;
  int n1 = mid - start + 1; 
  int n2 =  len - mid; 
  // Create temporary arrays and copy data to them.
  int lefthalf[n1], righthalf[n2]; 
  for (i = 0; i < n1; i++){
    lefthalf[i] = arr[start + i]; 
  }
  for (j = 0; j < n2; j++){ 
    righthalf[j] = arr[mid + 1+ j]; 
  }
  // Merge temporary arrays back into main array.
  i = 0; // Initial index of left half.
  j = 0; // Initial index of right half.
  k = start; // Initial index of merged subarray 
  while (i < n1 && j < n2) 
  { 
    if (lefthalf[i] <= righthalf[j]) 
    { 
      arr[k] = lefthalf[i]; 
      i++; 
    } 
    else
    { 
      arr[k] = righthalf[j]; 
      j++; 
    } 
    k++; 
  } 
  // If anything left in left half, copy it over and increment accordingly.
  while (i < n1) 
  { 
    arr[k] = lefthalf[i]; 
    i++; 
    k++; 
  } 
  // Copy anything left in right half accordingly and increment.
  while (j < n2) 
  { 
    arr[k] = righthalf[j]; 
    j++; 
    k++; 
  } 
}

这些更改之后,代码将正确生成两个完全排序的数组。