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