我正在寻找如何改进这个算法的建议。这是一个非常简单的算法,可以在数组中插入一个数字,并在inserction之后保持它的排序。这是一个很好用的函数,因此我需要快速运行它可能的。
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;
}
注意: 请避免内置功能。稍后将在程序集中重写此算法。
答案 0 :(得分:2)
有人已经提到为什么不对Binary Search进行修改。它是这样的 -
O(1)
时间内完成。在Bin-Search之后根据您想要放置新元素的位置向左或向右移动。所有这一切都将在O(log n)
时间内完成,这是一个血腥的快速,这是最快的。
答案 1 :(得分:2)
通常的方法(例如,在插入排序中)是从阵列移位元件的顶部向上开始并同时寻找插入点。以这种方式,您只触摸上面的元素插入。在伪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,因此循环将在运行数组底部之前停止。这称为 sentinel 。
看起来你从头开始搜索的原因是0终止了数组。如果你真的在速度之后,那么你应该改变数据结构并将数组的结尾记录为整数。这将使上述插入算法更快(平均1/2)插入算法。
添加最后要注意的是,编译器特别擅长优化这种插入的简单循环结构。如果使用-O4或等效编译包含此代码的模块,则不可能通过在汇编中重新编码来使代码更快。
答案 2 :(得分:0)
这段代码太可怕了;我甚至都不读它。通过修复缩进来改进它,然后我(像其他人一样)可以阅读它。
在C算法上导出汇编算法有两个原因,我可以提出。他们都疯了: