【发布时间】:2014-05-07 23:56:21
【问题描述】:
我实现了用于 100,000 个整数文件的 MergeSort 算法。它负责排序并收集文件中的反转。它适用于小型测试数组,但是一旦我插入实际文件,就会出现内存不足错误。我如何解决它? MergeSort 期间出现错误,我的 aux 数组中的元素数为 12,500 这是我的代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment_1
{
class Program
{
static void Main(string[] args)
{
List<int> data = File2Array("IntegerArray.txt");
int[] unsorted = data.ToArray();
List<string> inversions = new List<string>();
Sort(ref unsorted, ref inversions);
Console.WriteLine("number of inversions is: " + inversions.Count());
Console.ReadLine();
}
public static void Sort(ref int[] unsorted, ref List<string>inversions)
{
int size = unsorted.Length;
if (size == 1)
return;
int mid = size / 2;
int leftSize = mid;
int rightSize = size - leftSize;
int[] left = new int[leftSize];
int[] right = new int[rightSize];
Array.Copy(unsorted, 0, left, 0, leftSize);
Array.Copy(unsorted, mid, right, 0, rightSize);
Sort(ref left, ref inversions);
Sort(ref right, ref inversions);
int[] aux = new int[leftSize + rightSize];
for (int i = 0, j = 0, k = 0; k < aux.Length; k++)
{
if (left[i] < right[j])
{
aux[k] = left[i++];
// if left array is exhausted, copy the remaining right array elements over
if (i == leftSize)
{
Array.Copy(right, j, aux, ++k, rightSize - j);
unsorted = aux;
break;
}
}
else
{
int temp = i;
while (temp < leftSize)
{
inversions.Add(left[temp++] + "-" + right[j]);
}
aux[k] = right[j++];
if (j == rightSize)
{
Array.Copy(left, i, aux, ++k, leftSize - i);
unsorted = aux;
break;
}
}
}
}
public static List<int> File2Array(string file)
{
List<int> data = new List<int>();
using (StreamReader reader = new StreamReader(file))
{
int line;
do
{
int.TryParse(reader.ReadLine(), out line);
data.Add(line);
}
while (!reader.EndOfStream);
}
return data;
}
}
}
【问题讨论】:
-
我敢打赌你这里有一个无限循环。
-
没有无限循环。我用多个较小尺寸的输入对其进行了测试,一切正常。
-
在我看来,您正在存储 2 个数据副本。一个作为列表,另一个作为数组。坚持一个或另一个。您的排序例程也在递归地制作更多副本。
-
那么您的解决方案将不必要地消耗大量内存。使用 100000 个元素数组进行排序将分配 2 个 50000 个元素数组并进行递归,然后这 2 个递归中的每一个将分配 2 个 25000 个元素数组,直到您到达最后并拥有 50000 个 2 个元素数组。我认为您会在每次递归时分配 100000,并且需要 16 次以上的递归才能到达底部。
-
当您在下一级递归中为
L和R分配空间时,上面的数组将被保留。当您开始进行第一次合并操作时,您已经分配了 2 * log2(n) 个数组,总共有 ~n*2 个空格,并用从原始数组复制的数据填充了它们。在最坏的情况下,您应该为临时排序空间分配一次合并操作 - 自下而上分配而不是自上而下。