C#实现桶排序算法

3

大家晚上好!我创建了一个桶排序算法,但它报告了一个索引超出范围的错误。你能告诉我问题出在哪里吗?我自己找不到解决办法,所以向你们求助。

public int[] Sort(int[] unsortedSequence)
        {
            List<List<int>> buckets = new List<List<int>>();
            InitializeBuckets(buckets);
            Scatter(unsortedSequence, buckets);
            int i = 0;
            foreach (List<int> bucket in buckets)
            {
                int[] arr = bucket.ToArray();
                InsertionSort(arr);
                foreach (int d in arr)
                {
                    unsortedSequence[i++] = d;
                }
            }
            return unsortedSequence;
        }
        private static void Scatter(int[] array, List<List<int>> buckets)
        {
            foreach (int value in array)
            {
                int bucketNumber = GetBucketNumber(value);
                buckets[bucketNumber].Add(value);
            }
        }
        private static void InsertionSort(int[] array)
        {
            int j;
            int temp;

            for (int i = 1; i < array.Length; i++)
            {
                j = i;
                while (j > 0 && array[j] < array[j - 1])
                {
                    temp = array[j];
                    array[j] = array[j - 1];
                    array[j - 1] = temp;
                    j--;
                }
            }
        }
        private static int GetBucketNumber(int value)
        {
            int val = value * 10;

            return val;
        }

        private static void InitializeBuckets(List<List<int>> buckets)
        {
            for (int i = 0; i < 10; i++)
            {
                List<int> a = new List<int>();
                buckets.Add(a);
            }
        }

2
使用调试器并逐步执行代码,找出您超出数组边界的位置。只有当您超出数组边界时才会导致“索引超出范围”错误,并且您可以逐步执行代码以查找导致此问题发生的逻辑错误。如果您不知道如何使用调试器,现在是学习的绝佳时机;逐步执行代码以解决这种问题确实并不难。 - Ken White
我找不到问题。 - finsters
2
那就再仔细看看吧。我上一条评论才发了4分钟,根本没有足够的时间来尝试在调试器中逐步执行代码。至少要努力做点什么。不到4分钟的努力甚至不值得一提。使用调试器 - 它将是你编程工具包中最有用的工具,并且你需要学会使用它。现在就开始吧。错误消息告诉你问题出现的位置以及无效索引值是什么,这已经足够开始调试了。 - Ken White
2个回答

2

我不确定你在排序时使用了什么逻辑,但我明白你为什么会得到索引超出范围的错误。

代码错误

你创建了10个桶,现在你试图通过将当前数组值乘以10来生成桶编号。

例如,如果您当前的数组值为2,则生成的桶编号将为20。由于你只有10个桶,所以Scatter()方法会报错。

 private static void Scatter(int[] array, List<List<int>> buckets)
 {
     foreach (int value in array)
     {
         int bucketNumber = GetBucketNumber(value);
         buckets[bucketNumber].Add(value); // ERROR HERE
     }
 }

解决方案

实际上,GetBucketNumber() 方法存在问题。你应该使用取余而不是乘法。请使用以下方法进行更改。

private static int GetBucketNumber(int value)
{
    int val = value % 10;
    return val;
}

你必须做的

在求助前,尽量自己努力解决问题。首先在纸上运行程序,确认逻辑后再开始编码。相信自己,给自己足够的时间去尝试。享受编程的乐趣。


1
在我回答之前,我强烈建议您在寻求外部帮助之前始终先尝试解决问题。我并不一定认为您没有尝试过,但是通过调试器轻松地识别出了这个问题。
如果这是编程中您不太熟悉的方面,我强烈建议将其作为优先学习的内容-这只会使您成为更好的开发人员。
问题出现在Scatter方法的此处: int bucketNumber = GetBucketNumber(value); buckets[bucketNumber].Add(value); 异常发生是因为GetBucketNumber将输入乘以10,但您正在使用该乘以值作为buckets的索引。

我知道问题出在哪里,因为错误输出了不正确的行,但我不知道如何解决这个问题,所以我来到这里。这对我来说是一门新语言,可能我不知道基础知识。 - finsters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接