Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.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
C 改进该算法_C_Arrays_Algorithm_Sorting - Fatal编程技术网

C 改进该算法

C 改进该算法,c,arrays,algorithm,sorting,C,Arrays,Algorithm,Sorting,我正在寻找如何改进该算法的建议。这是一个非常简单的算法,可以在数组中插入一个数字,并在插入后保持其排序。它是一个使用良好的函数,因此我需要尽可能快地运行它 static inline void sort_insert(int *arr,int target,int size) { int i, at; for(i = 0; i < size && arr[i] != 0 && arr[i] < target; i++) /* do

我正在寻找如何改进该算法的建议。这是一个非常简单的算法,可以在数组中插入一个数字,并在插入后保持其排序。它是一个使用良好的函数,因此我需要尽可能快地运行它

static inline void sort_insert(int *arr,int target,int size)
{
  int i, at; 

  for(i = 0; i < size && arr[i] != 0 && arr[i] < target; i++)
    /* do nothing */;

  at = i; // insertion point

  /* if the number will be inserted into last postion,we don't need loop */
  if (at == size) {
    arr[at - 1] = target;
    return;
  }

  for(i = size - 1; i > at; i--)
    arr[i] = arr[i - 1];
  arr[at] = target;
}
static inline void sort\u insert(int*arr,int-target,int-size)
{
int i,at;
对于(i=0;iat;i--)
arr[i]=arr[i-1];
arr[at]=目标;
}
注意:
请避免使用内置函数。此算法将在以后的汇编中重写。

正如有人已经提到的,为什么不应用对的修改。事情是这样的-

  • 首先搜索要插入到数组A中的元素X
  • 在搜索结束时(是否找到并不重要),插入新元素
  • 如果要为类似元素处理插入顺序(例如,要插入X=3,但A中已存在3,则也可以在
    O(1)
    时间内完成。在Bin搜索后,根据您希望放置新元素的位置向左或向右移动

  • 所有这一切都将在
    O(logn)
    时间内完成,时间非常快,尽可能快。

    通常的完成方式(例如插入排序)从数组顶部开始,向上移动元素,同时查找插入点。通过这种方式,您只需触摸插入点上方的元素。在伪C中:

    // a[0] t0 a[n_elements - 1] contain sorted data
    // Insert val_to_insert in sorted order by shifting up until we find the right place
    for (i = n_elements; i > 0 && a[i - 1] > val_to_insert; i--)
      a[i] = a[i - 1];
    // i is now the insertion point
    a[i] = val_to_insert;
    
    您的算法必须涉及所有元素。平均而言,插入排序方法将快1/2

    另一个技巧是将一个“虚拟”-无穷大值保持在位置0,这样就可以消除
    i>0
    比较。另一个条件在达到该值时总是为false,因此循环将在从数组底部运行之前停止。这称为哨兵

    看起来您从一开始就搜索的原因是0终止了数组。如果您真的追求速度,那么您应该更改数据结构并将数组的结尾记录为整数计数。这将启用上述更快(平均1/2)的插入算法


    添加最后一点需要注意的是,编译器在优化类似插入的简单循环结构方面特别出色。如果您使用-O4或等效代码编译包含此代码的模块,则不太可能通过在汇编中重新编码使代码运行得更快。

    此代码非常糟糕;我甚至不打算阅读它。通过修正缩进来改进它,然后我(和其他人一样)可能会阅读它

    在C算法的基础上推导汇编算法有两个原因,我可以想到。它们都是疯狂的:

  • 你认为C和汇编有什么共同点吗?除了作为编程语言之外,它们几乎没有任何共同点。别忘了这一点;学习汇编就像它与C有“共同”的特性一样,或者学习C就像它有“共同”的特性一样,是没有意义的使用汇编,因为C不绑定到一个特定的体系结构。您可能会认为“这在C中有效,因为它在我的体系结构中有效”,但鸡可能会也可能不会在没有头的情况下跑来跑去。C有未定义的行为。未定义的行为可能会在你的鞋子中产生预期的结果,但C并不是专为你的鞋子设计的

  • 你认为你可以手动优化你的程序吗?你的编译器可能会产生比你更优化的汇编。毕竟,编译器是由多年来一直在编写汇编的专家编写的。同样,C标准库也是由专家编写的。你也许可以内联标准库qsort/B搜索并转换为汇编y使用编译器。别忘了分析编译器生成的“-O3”版本,并将其与您对程序集输出所做的每一次“优化”进行比较;通过有一些标准的东西作为比较的基础,我认为您会发现您浪费了数天、数周、数月或数年的时间来获得微不足道的性能提升

  • 你有一个流氓;在你的第一个for循环中。可能更针对你的问题。我会使用
    memmove()用于移动数组数据:而不是一个一个地手动复制它。根据体系结构的使用,在更大的块中复制可能更有效。考虑编辑这个帖子来提出问题而不是要求。我尝试使用BScript,但是我不能自己写。如果<代码> x>代码>不是数组(非常常见)。我如何知道它是否是第一个小于
    x
    ?抱歉。即使你在O(logn)中找到插入点,上面元素的移动也需要O(n)。而且它也不能处理0终止其数组的事实。“你认为你可以手动优化你的程序吗?”选择并不是为什么要在汇编中编写的原因。是两个不同的程序。谁说的不同?@Jack确实如此。正如我在回答中所说,手动优化是我能看到的从C算法派生汇编算法的两个原因之一。然而,如果要在汇编中重写整个算法,为什么要在C?B中编写呢因为尽管我在寻找相同的算法,但在不同的语言中,它们做的工作并不完全相同。汇编程序与C程序非常不同。第一个是个人程序。我问这个问题只是为了方便,而不是制作两个主题相同的线程,然后返回一个“双主题”,“作为副本关闭”作为anwer。但这似乎是我的错误。不客气。既然人们继续建议使用二进制搜索,我想指出它是没有用的。无论如何,你需要将元素向上移动。可能还不如一箭双雕。我还将添加一条关于尝试使用二进制搜索的注释