Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 什么是适合嵌入式系统的排序算法?_Algorithm_Sorting_Embedded - Fatal编程技术网

Algorithm 什么是适合嵌入式系统的排序算法?

Algorithm 什么是适合嵌入式系统的排序算法?,algorithm,sorting,embedded,Algorithm,Sorting,Embedded,我正在为一个嵌入式系统开发软件,我需要实现一个排序例程,我在选择最佳解决方案时遇到了困难。我的要求如下: 因为这是一个内存非常有限的系统,所以空间复杂性是一个主要因素 由于要排序的元素数量通常很小,而且排序只是偶尔发生,因此时间复杂性不一定是主要因素 我的应用程序需要一个稳定的算法 因为这是一个嵌入式系统,所以代码大小是一个因素 无法保证数据最初将以近乎排序的顺序排列 我考虑了以下算法: 气泡排序(是的,尽管我不好意思这么说) 侏儒排序 插入排序 就地合并排序(虽然在我看来,链表比数组更理想?

我正在为一个嵌入式系统开发软件,我需要实现一个排序例程,我在选择最佳解决方案时遇到了困难。我的要求如下:

  • 因为这是一个内存非常有限的系统,所以空间复杂性是一个主要因素
  • 由于要排序的元素数量通常很小,而且排序只是偶尔发生,因此时间复杂性不一定是主要因素
  • 我的应用程序需要一个稳定的算法
  • 因为这是一个嵌入式系统,所以代码大小是一个因素
  • 无法保证数据最初将以近乎排序的顺序排列
  • 我考虑了以下算法:

    • 气泡排序(是的,尽管我不好意思这么说)
    • 侏儒排序
    • 插入排序
    • 就地合并排序(虽然在我看来,链表比数组更理想?)

    虽然答案(就我的具体情况而言)很可能是“嗯,嗯,没关系,我们只关心使用冒泡排序”,但这个答案不是很有用一般来说,什么样的排序算法对嵌入式系统有用?

    不要为冒泡排序感到羞耻,它有自己的位置。如果您的数据集很小,那么很容易编写代码,而且如果您做得正确,它是稳定的(永远不要交换相等的元素)

    如果您的数据主要是通过在每次传递时交替方向进行排序,那么它也可能会非常快。我知道你说它一开始并没有被分类,我说的是,如果你分类然后坚持下去,它会变成这样的可能性。在这两种情况下,如果数据集的大小很小,那么它是否完全未排序实际上并不重要

    如果您在另一个答案的评论中提到,您的数据集大小约为11,则情况尤其如此。如果没有一个明确设计为故意制造恐怖的排序算法,那么任何算法都可以很容易地以足够快的速度处理这样的大小

    如果您的环境没有提供稳定的排序,那么考虑到您的约束和属性,我会选择冒泡排序


    事实上,使用下面的程序和
    time
    实用程序,我发现
    qsort
    和冒泡排序所用的CPU时间只有在元素计数达到10000时才会产生影响

    而且,即使在那时,这种泡沫也只花了不到半秒钟的时间。除非你每秒要做很多排序,否则这是无关紧要的

    #include <stdio.h>
    #include <stdlib.h>
    
    static int data[10000];
    #define SZDATA (sizeof (*data))
    #define NMDATA (sizeof (data) / sizeof (*data))
    
    int compfn (const void *a, const void *b) {
        if (*((int*)a) > *((int*)b))
            return 1;
        if (*((int*)a) < *((int*)b))
            return -1;
        return 0;
    }
    
    int main (void) {
        int i, tmp, swapped, count;
    
        for (i = 0; i < NMDATA; i++)
            data[i] = (i * 3) % 11;
    
        if (0) {
            qsort (data, NMDATA, SZDATA, compfn);
        } else {
            swapped = 1;
            count = NMDATA;
            while (swapped) {
                swapped = 0;
                for (i = 1; i < count; i++) {
                    if (data[i] < data[i-1]) {
                        tmp = data[i];
                        data[i] = data[i-1];
                        data[i-1] = tmp;
                        swapped = 1;
                    }
                }
                count --;
            }
        }
    
        //for (i = 0; i < NMDATA; i++)
            //printf ("%10d\n", data[i]);
    
        return 0;
    }
    
    我怀疑使用小数据集进行更快的冒泡排序是因为缺少函数调用

    需要注意的是,对于较小的数据集,算法的效率通常不重要,因为像big-O这样的东西通常与数据集变大相关

    但是,此测试是在我的环境中完成的,您的环境可能会有很大差异。我建议在您的环境中执行相同的测量——实现冒泡排序,只考虑在必要时移动到更复杂的算法。


    在一位评论员的建议下,我使用
    srand(42)
    rand()
    重新运行测试,以填充数组元素。在这种情况下,气泡排序的结果只稍微差一点,10000个元素的结果是642毫秒对413毫秒,1000个元素的结果是82毫秒对74毫秒

    考虑到问题中的约束条件(小元素计数、不频繁排序、稳定性要求、低空间复杂度),与任何更复杂的算法相比,我仍然更喜欢气泡排序的简单性


    不过,请记住我之前的建议:您需要在自己的环境中计时。结果可能大不相同。您可以使用我提供的代码作为这样做的基线。说真的,无论你选择哪种方法,只要不到一秒钟,就足以满足你的需要。

    系统是否嵌入并不重要。重要的是您列出的因素:代码大小限制、可用ram、所需速度和元素数量

    正如您所概述的,冒泡排序是一个完全可以接受的解决方案:它小、可预测、易于内存,并且非常易于实现和调试。我在20世纪80年代初看到了一个证据,得出结论:对于n,冒泡排序是时间最优的≤ 11现代快速运动可能会稍微改变这一点,但我怀疑盈亏平衡可能会减少很多


    要使不稳定的排序算法稳定,请添加包含原始位置的排序键。仅当主键是平局键时才参考辅助键。

    插入排序也很好,它在实践中运行速度快,稳定且到位。它与gnome排序非常相关,在实践中更快,但对于gnome排序,代码更小,占用的辅助空间更少(不是大O,区别在于常量)

    编辑:是的,我搞砸了一点,把它们颠倒过来了——我可能不应该在喝咖啡之前回答问题。。它以前说过,插入排序比gnome排序的代码和空间要少

    删除“在嵌入式系统上”并将问题改为“一般来说,什么排序算法有用”。下一步,试试看!到目前为止,您尝试了什么,内存消耗是多少,执行时间是多少,代码大小是多少

    嵌入式或台式机您应该执行这些实验并提出这些问题。没有一般的答案,因为没有一般的要求。根据需求,每个解决方案都有其位置。一刀切不适合任何人。真正的问题是您的需求是什么,然后您需要担心实现和满足这些需求。是否需要一种排序,是否可以用另一种方式解决?这种类型在您的总体绩效数字中占多少比例?帐篷里的其他长杆是什么

    绝对法
    Data size | qsort | bubble
    ----------+-------+-------
          100 |    61 |     76
              |    76 |     76
              |    77 |     61
              |    61 |     60
              |    61 |     61  avg qsort = 67, bubble = 67
    
         1000 |    77 |     93
              |    61 |     45
              |    76 |     77
              |    77 |     76
              |    76 |     77  avg qsort = 73, bubble = 74
              |       |
        10000 |    92 |    414
              |    77 |    413
              |    61 |    413
              |    76 |    405
              |    61 |    421  avg qsort = 73, bubble = 413