Stackoverflow仅适用于非常大的ArrayLists

时间:2018-05-02 00:20:14

标签: c# recursion arraylist console

我正在使用插入排序算法的递归版本来根据随机生成的整数属性对5000个对象进行排序,但是我一直只在这个大小的ArrayList上获得stackoverflow异常,而对其他的ArrayLists工作正常尺寸。

我使用Console.WriteLine来查看我的一个方法中“位置”整数的变化,并在跳过一行并给出一个stackoverflow异常之前结束于4719。我应该怎么解决这个问题?

我还应该提一下,在同一个Visual Studio解决方案中测试插入排序的迭代版本并使用相同大小的对象的ArrayList时,我没有得到堆栈溢出异常。

我的递归插入排序代码如下(AL是ArrayList):

public void IS()
{
    ISRM(0);
}

private void ISRM(int position)
{
    if (position == AL.Count)
        return;

    Console.WriteLine(position);
    int PositionNext = position + 1;
    ISRMNext(position, PositionNext);
    ISRM(position + 1);
}

private void ISRMNext(int position, int PositionNext)
{
    if ((PositionNext == 0) || (PositionNext == AL.Count))
        return;

    Webpage EntryNext = (Webpage)AL[PositionNext];
    Webpage EntryBefore = (Webpage)AL[PositionNext - 1];

    if (EntryBefore.getVisitCount() < EntryNext.getVisitCount())
    {
        Webpage temp = EntryBefore;
        AL[PositionNext - 1] = AL[PositionNext];
        AL[PositionNext] = temp;
    }

    ISRMNext(position, PositionNext - 1);
}

1 个答案:

答案 0 :(得分:1)

嗯,首先,由于几个原因,通过递归调用进行排序是一个坏主意。

  1. 正如您已经发现的那样,由于堆栈的大小有限,很容易导致堆栈溢出。

  2. 根据定义,它的性能会很差,因为与whilefor运算符迭代到普通的运算符相比,函数调用和在堆栈上配置本地函数上下文的操作要昂贵得多集合。

  3. 这是为什么@ Zer0可能提出这个原因的两个原因,但还有更多原因。

    1. 等待你的现成ArrayList.Sort()方法需要自定义比较器。您所需要的只是根据您想要的任何规则为您的自定义对象编写所述比较器并调用Sort(your_comparator)。就是这样。你不需要重新发明轮子实现你自己的排序方法本身 - 除非实现排序方法是你的程序的实际目标......但我真的怀疑它。
    2. 所以,它可能是这样的(未经测试!):

      class MyComparer : IComparer
      {
          public int Compare(object x, object y)
          {
              var _x = ((Webpage) x).getVisitCount();
              var _y = ((Webpage) y).getVisitCount();
              if (_x < _y)
              {
                  return -1;
              }
      
              if (_x > _y)
              {
                  return 1;
              }
      
              return 0;
          }
      }
      

      用法:

      var myAL = new ArrayList();
      // ... filling up the myAL
      myAL.Sort(new MyComparer());