【问题标题】:Why is my selection sort algorithm consistently faster than my insertion sort?为什么我的选择排序算法总是比我的插入排序快?
【发布时间】:2017-04-12 07:29:43
【问题描述】:

“已排序”是一个随机生成的、最初未排序的整数数组

private void insertion_Click(object sender, EventArgs e)
{
    Stopwatch sw = new Stopwatch();
    sw.Start();
    for(int i = 1; i < Sorted.Length; i++)
    {
        int j = i;
        while(j>0 && Sorted[j-1] > Sorted[j])
        {
            swap(Sorted, j - 1, j);
            j -= 1;
        }
    }
    sw.Stop();

    IsSorted = true;
    UpdateButtons(IsSorted);
    MessageBox.Show($"Insertion sort took {(sw.ElapsedMilliseconds).ToString()} milliseconds", "Insertion sort");
}


//Selection sort
private void selection_Click(object sender, EventArgs e)
{
    Stopwatch sw = new Stopwatch();
    sw.Start();
    for(int i = 0; i < Sorted.Length-1; i++)
    {
        int CurrMinIndex = i;
        for(int j = i; j < Sorted.Length; j++)
        {
            if(Sorted[j] < Sorted[CurrMinIndex])
            {
                CurrMinIndex = j;
            }
        }

        if(CurrMinIndex != i)
        {
            swap(Sorted, CurrMinIndex, i);
        }
    }
    sw.Stop();

    IsSorted = true;
    UpdateButtons(IsSorted);
    MessageBox.Show($"Selection sort took {(sw.ElapsedMilliseconds).ToString()} milliseconds", "Selection Sort");
}

我正在设计一个 C# WPF 应用程序,它对随机生成的列表进行排序,然后以毫秒为单位输出完成时间。我知道插入排序平均应该比选择排序更好,但我的结果告诉我不然。我什至没有看到插入排序的时间接近选择排序。事实上,我的选择排序算法似乎总是快两倍!有人看到这里的问题吗?我以为我已经对这两种算法做了一些很一般的形式,但是我是否不小心优化了?

编辑:这是我用来填充列表的算法:

Sorted = new int[ListSize];  //initialize/populate unsorted array
Random Rand = new Random();
for (int i = 0; i < ListSize; i++)
{
     Sorted[i] = Rand.Next(-1000, 1000);
}

【问题讨论】:

  • 列表要排序多长时间?初始排序也会产生影响(您似乎做的反转数组是复杂性的特殊情况,例如,纯快速排序在这种情况下非常糟糕)。
  • 完全随机。提示用户输入他们想要的大小的整数值,例如 2000 或 22399 等,然后生成并存储一个随机列表,然后可以使用他们想要的任何算法对其进行排序。我更新了我的帖子以显示我是如何填充列表的。
  • @Evk:选择排序在已经排序的数组上并没有明显更快,因为它仍然需要进行所有(n^2 -n)/2 比较。它不会进行任何交换,但不会提前退出。
  • 它们肯定会重置。我也可以通过单击应用程序上的按钮进行检查。
  • @JimMischel 但我的意思是,如果您首先使用插入排序对完全随机数组进行排序,然后将选择排序应用于此(已排序)数组 - 它应该比随机数组上的插入排序更快,对吧?

标签: c# algorithm sorting time


【解决方案1】:

您的插入排序实现不够好。您在寻找元素 P 的位置时进行完全交换,但记住 P 就足够了,将较大的元素向上移动(半交换?),然后插入 P

     int j = i;
     int P = Sorted[j];
     while(j>0 && Sorted[j-1] > P)
        {
            Sorted[j] = Sorted [j-1];
            j--;
        };
    Sorted[j] = P; 

【讨论】:

  • 嗯。该代码给了我一个 OutOfBounds 异常
  • 我的错,应该是Sorted[j] = P;
  • 啊,非常感谢。这似乎起到了作用。不过,我仍然有点不确定。如果我必须为我的程序优化插入排序,这是否意味着我的选择排序算法得到了优化?我以为我使用了这些算法的非常基本的版本,所以我不确定为什么会有这样的时间差异。
  • 您的选择排序是最佳的。请注意,选择总是进行预定义的比较次数 (n*(n-1)/2)。插入排序的比较次数取决于数据集的顺序,平均比较少。
猜你喜欢
  • 1970-01-01
  • 2016-02-18
  • 1970-01-01
  • 1970-01-01
  • 2016-02-01
  • 2022-01-15
  • 2011-11-30
  • 2015-06-25
  • 2017-07-30
相关资源
最近更新 更多