合并C#中的排序实现-StackOverflow异常

问题描述

大家! 我正在尝试在C#中实现合并排序算法。我的代码中有一个StackOverflow异常。 我正在尝试找出问题所在,但无法解决。

using System;

class MainClass {
  
  static void merge(int[] arr,int leftIndex,int endLeftIndex,int endRightIndex){
    // leftArr [leftIndex ... endLeftIndex]
    // rightArr [endLeftIndex + 1 ...  endRightIndex]
    int leftArrLength = endLeftIndex - leftIndex + 1;
    int rightArrLength = endRightIndex - endLeftIndex;
    
    int[] leftArr = new int[leftArrLength],rightArr = new int[rightArrLength];

    // Copying the data from the parent Array to the leftArr & rightArr
    for(int i = 0; i < leftArrLength; i++)
      leftArr[i] = arr[leftIndex + i];
    for(int j = 0; j < rightArrLength; j++)
      rightArr[j] = arr[endLeftIndex + j + 1];

    // the start index of the array that will be merged
    int mergedArrIndex = leftIndex;

    // set two start pointers for both left and right arrays
    int leftIndexMerge = 0,rightIndexMerge = 0;

    // the merging operation
    while(leftIndexMerge < leftArrLength && rightIndexMerge < rightArrLength){
      if(leftArr[leftIndexMerge] < rightArr[rightIndexMerge])
        arr[mergedArrIndex++] = leftArr[leftIndexMerge++];
      else
        arr[mergedArrIndex++] = rightArr[rightIndexMerge++];
    }
    
    // copying the rest elements
    while(leftIndexMerge < leftArrLength)
      arr[mergedArrIndex++] = leftArr[leftIndexMerge++];
    
    while(rightIndexMerge < rightArrLength)
      arr[mergedArrIndex++] = rightArr[rightIndexMerge++];
  }
  
  static void mergeSort(int[] arr,int endRightIndex){
    if(leftIndex < endRightIndex){
      // leftArr [leftIndex ... m]
      // rightArr [m + 1 ...  endRightIndex]
      int m = leftIndex + (endRightIndex - 1) / 2;
      mergeSort(arr,leftIndex,m);
      mergeSort(arr,m + 1,endRightIndex);
      merge(arr,m,endRightIndex);
    }
  }
  public static void Main (string[] args) {
    int[] arr = {1,2,5,10,1,3,4,4};
    mergeSort(arr,arr.Length);
    foreach(int i in arr) Console.WriteLine(i);
  }
}

查看repl.it中的代码:https://repl.it/@MohamedMarzouk/MergeSortImplementationInCSharp

解决方法

您遇到2个问题

导致堆栈溢出的第一个

// int m = leftIndex + (endRightIndex - 1) / 2;
// should be
int m = leftIndex + (endRightIndex - leftIndex) / 2;

查看源代码,您只是将l误认为1

enter image description here

以及以下会给您索引超出范围错误的错误

// mergeSort(arr,arr.Length);
// should be
mergeSort(arr,arr.Length-1);

没有任何借口:)

,

您的代码中有2个问题:

  • 中间索引计算不正确:int m = leftIndex + (endRightIndex - 1) / 2;应该

      int m = leftIndex + (endRightIndex - leftIndex) / 2;
    
  • Main进行初始呼叫传递的
  • 参数不正确:mergeSort(arr,arr.Length)应该

      mergeSort(arr,arr.Length - 1);
    

这表明包括开始和结束边界索引的约定容易出错。如果排除endRightIndexendLeftIndex ,则不再需要+1 / -1调整。我希望教程会停止教授这种废话。

这是简化版:

using System;

class MainClass {
 
  static void merge(int[] arr,int leftIndex,int rightIndex,int endIndex) {
     // leftArr [leftIndex ... endLeftIndex)
     // rightArr [endLeftIndex ...  endIndex)
     int leftArrLength = rightIndex - leftIndex;
     int rightArrLength = endIndex - RightIndex;
   
     int[] leftArr = new int[leftArrLength];
     int[] rightArr = new int[rightArrLength];

     // Copying the data from the parent Array to the leftArr & rightArr
     for (int i = 0; i < leftArrLength; i++)
        leftArr[i] = arr[leftIndex + i];
     for (int j = 0; j < rightArrLength; j++)
        rightArr[j] = arr[rightIndex + j];

     // the start index of the array that will be merged
     int mergedArrIndex = leftIndex;

     // set two start pointers for both left and right arrays
     int leftIndexMerge = 0,rightIndexMerge = 0;

     // the merging operation
     while (leftIndexMerge < leftArrLength && rightIndexMerge < rightArrLength) {
        if (leftArr[leftIndexMerge] <= rightArr[rightIndexMerge])
           arr[mergedArrIndex++] = leftArr[leftIndexMerge++];
        else
           arr[mergedArrIndex++] = rightArr[rightIndexMerge++];
     }
   
     // copying the rest elements
     while (leftIndexMerge < leftArrLength)
        arr[mergedArrIndex++] = leftArr[leftIndexMerge++];
   
     // This final loop is actually redundant: these elements are already in place
     //while (rightIndexMerge < rightArrLength)
     //   arr[mergedArrIndex++] = rightArr[rightIndexMerge++];
  }
 
  static void mergeSort(int[] arr,int endIndex) {
     if (endIndex - leftIndex >= 2) {
        // leftArr [leftIndex ... m)
        // rightArr [m ...  endIndex)
        int m = leftIndex + (endIndex - leftIndex) / 2;
        mergeSort(arr,leftIndex,m);
        mergeSort(arr,m,endIndex);
        merge(arr,endIndex);
     }
  }

  public static void Main(string[] args) {
     int[] arr = { 1,2,5,10,1,3,4,4 };
     mergeSort(arr,arr.Length);
     foreach (int n in arr)
        Console.WriteLine(n);
  }
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...