【问题标题】:Runtime of Bubble sort algorithms in CC 中冒泡排序算法的运行时
【发布时间】:2019-04-26 14:50:17
【问题描述】:

您好,我正在我的大学里做关于数据结构和算法的讲座。我正在做关于分析排序算法的任务。作业需要包含测量算法运行时间的报告。 TA给了我们30000个整数的三个数据集(升序、降序、随机)

我认为对降序数据进行排序比对随机排序的数据进行排序要多。但在我的冒泡排序算法中,结果却相反。

对数字进行降序排序需要 2.453 秒的实时时间和 2.409 秒的用户时间,对数字进行随机排序需要 3.217 秒的实时时间和 3.159 秒的用户时间。这个结果也与我的选择排序算法有关。降序数不是最坏的情况吗?

//file is opened at main function
int* bubble_prj4(FILE *fp_in)
{
    int i, j, temp;

    //arr is declared in header file
    arr = (int*)malloc(sizeof(int) * 30000);
    fread(arr, sizeof(int), 30000, fp_in);
    for(i = 0; i < 29999; i++)
        for(j = 29999; j > i; j--)
            if(arr[j] < arr[j - 1])
            {
                temp = arr[j];
                arr[j] = arr[j - 1];
                arr[j - 1] = temp;
            }
    return arr;
}

这是我第一次在这里提问。我不知道我做得对。

【问题讨论】:

  • 你在哪里看过? Wikipedia on Bubble Sort vs Insertion Sort vs Selection Sort——我现在正好在使用这些页面,所以我打开了标签。
  • 那些时间有多可靠?您可能多次运行它们并获得了稳定的结果。您应该检查fread() 调用是否返回30000。 (我会在您的代码中添加两对大括号,每个 for 循环也有一对。)
  • @JonathanLeffler 哦,我刚刚添加了这些大括号。我不明白你对fread() 的说法。
  • 一般来说,您需要检查如果您希望读取 30,000 个整数,fread() 报告它实际上能够读取 30,000 个整数,而不是更小的整数。
  • 哦,我明白了。我不太了解fread() 的返回。我刚刚通过 gdb 查过了。

标签: c time-complexity bubble-sort


【解决方案1】:

我运行了你的测试。以下是我在大小为 30,000 的三个不同数据集上的结果:

  dataset  |  time (s)  |   swaps
-----------+------------+----------
random     |  3.588447  | 221476595
descending |  2.588694  | 449985000
ascending  |  1.582666  |         0

这里发生了什么?为什么随机数据集比“最坏情况”下降数据集慢?

答案似乎是branch prediction。 CPU 会猜测代码中将采用哪个分支,执行它,并且在下降的数据集中 100% 的时间是正确的。这会导致性能显着提升,并且一直是more elegantly explained before

话虽如此,例程涉及相同数量的比较,时间复杂度在所有情况下都是 O(n2)。

【讨论】:

  • 哇。我很难通过第一个链接理解它,但我通过第二个链接理解它。实际上这个问题似乎超出了我的课程范围,(我们必须使用优化级别 -O0 进行编译。)但对我来说非常有意义。谢谢。
  • @Jiseong:你必须用-O0编译(没有优化,使用GCC)?这很奇怪。好吧,您还应该使用更多选项进行编译——我推荐 gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes … 并且在程序编译干净之前不要运行程序(事实上,-Werror 意味着您将无法运行程序,直到它编译干净) .然后,如有必要,您可以将优化放回-O0 以满足课程相当特殊的要求,但-O3 级别标识的一些问题不会在-O0 报告。
  • @JonathanLeffler 感谢您推荐该选项。做另一个编码对我有帮助。但是我的意思是“必须用-O0编译”是Makefile和源文件和头文件的目录结构只是由TA给出的。我无法完全理解讲师的意图,但这只是作业。
  • 您可以在执行任务时编辑 makefile 以更加严格。当您要提交时,请改用官方副本。除了你的程序运行缓慢(因为它没有优化)之外,应该没有问题。
猜你喜欢
  • 2018-08-11
  • 2013-07-13
  • 1970-01-01
  • 2016-03-19
  • 1970-01-01
  • 1970-01-01
  • 2013-09-04
  • 2013-11-02
  • 1970-01-01
相关资源
最近更新 更多