【问题标题】:Insertion sort stops working after million input百万输入后插入排序停止工作
【发布时间】:2016-10-13 12:48:30
【问题描述】:

我已经实现了插入排序,我猜这很好。它从文件中读取并为输入 10,100,1000,10000,10000 正确排序。

但是,当我投入一百万美元时,它什么也没做。我什至等了 10 分钟来检查它是否太慢。
我动态创建了我的数组,并尝试了合并排序。一百万输入它工作得非常好,但我不明白为什么只有插入排序算法不能处理一百万输入。这是代码的一部分;

#include <iostream>
#include <fstream>

using namespace std;

void InsertionSort(int* array, int& size);
int main()
{
    int size;
    ifstream myfile("data.txt");
    myfile.open("data.txt");
    cout << "How many elements do you want to read" << endl;
    cin >> size;

    int* array = new int[size];
    for (int i = 0; i < size; i++) {
        myfile >> array[i];
    }

    InsertionSort(array, size);
    delete[] array;
}
void InsertionSort(int* array, int& size)
{
    int temp, j;

    for (int i = 1; i < size; i++) {
        j = i;
        while (j > 0 && array[j - 1] > array[j]) {
            temp = array[j];
            array[j] = array[j - 1];
            array[j - 1] = temp;
            j--;
        }
    }
}

【问题讨论】:

  • 只需附加一个调试器,然后我猜测并查看它的作用。如果它仍然在您的分拣程序中,则需要很长时间。或者让它运行几个小时,然后再回来查看。
  • @Hayt 谢谢,我会努力的。希望每个人都像你一样善良。每个人都想在这里证明一些东西,而不是帮助任何人
  • @G.Rust FWIW,我认为您的问题适合 SO。如果您希望人们给您提示/最佳实践,我邀请您到codereview。否则,请继续在这里发帖。 :)
  • 我很困惑为什么这被否决了。当然,代码不是最好的,帖子可以使用一些格式,但问题本身对我来说似乎是合理的。
  • @GManNickG 是这么想的,但他们虽然没用,因此暂时禁止我提问..

标签: c++ algorithm sorting input insertion-sort


【解决方案1】:

您的程序运行时间为 O(n²),因为您有两个嵌套循环,它们都取决于输入的大小。因此,一旦您从 10,000 个元素增加到 1,000,000 个元素,您的程序将需要 100² = 一万倍的时间才能完成。此外,可能您的数据集以前适合处理器的缓存,但有 100 万个元素时它不再适合,所以这会更慢。

O(n²) 算法使事情变得非常缓慢非常快。输入大小为 10⁶,这意味着您的程序将按照 10¹² 的顺序完成操作。假设您的处理器最多以每秒 10⁹ 次操作的速度运行,并且您的算法每一步肯定会使用多个操作,那么您的程序将需要 10³ 秒以上的时间才能完成。

【讨论】:

  • 当我在排序后尝试打印数组时,它仍然需要显示一些输出。它永远不会。 @G.Sliepen
  • 算法没有立方增长。
  • @G.Rust 假设有一个三重循环:你怎么知道你等了足够长的时间?显然你没有等到程序结束。正如其他人已经告诉您的那样,使用 O(n^3) 从 10K 到 1M 的速度要慢 10000 倍。
  • 嗯,它以前对我来说就像一个 MCVE。但我调整了我的答案。这仍然需要很多时间。
  • @G.Rust 只是为了“缓慢”地迭代到 1Mio。你会看到的。像200k。然后是 300k 等。
【解决方案2】:

在最坏的情况下,合并排序是 O(n lg(n)),平均而言,插入排序是二次的(不仅在最坏的情况下)。
差别很大。

假设您有两个算法,A 和 B。

对于任何大小为 n 的输入,A 进行 n2 次操作,而 B 进行 n*lg(n) 次操作。

如果将输入加倍,算法 A 需要 (2n)2 = 4n2 次操作 - 是原来的四倍。

B 取 2n * lg(2n) = 2n * (lg(n) + 1) = 2n * lg(n) + 2 = 2(n * lg(n) + 1),这只是一点点超过两倍。

为了说明从 10,000 到 1,000,000 个元素时的区别(为简单起见,使用十对数):

10,000 * 10,000 = 100,000,000 
1,000,000 * 1,000,000 = 1,000,000,000,000

那是 10,000 倍。

10,000 * log(10,000) = 40,000
1,000,000 * log(1,000,000) = 6,000,000

那是 150 倍。

所以也就不足为奇了,如果一万个案例所用的时间大致相同,那么对于一万个案例,插入排序将比合并排序花费更长的时间。

【讨论】:

    猜你喜欢
    • 2014-06-04
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2015-02-07
    • 1970-01-01
    相关资源
    最近更新 更多