带顺序开关的插入排序功能
Insertion sort function with order switch
我试图编写一个插入排序函数,该函数将根据其参数(order
)的符号在升序和降序之间切换。它可以工作,但看起来不太好,因为我用作开关的条件运算符会给内部循环的每次迭代增加一些开销。所以我想征求你的意见,告诉我如何写一个更好的函数版本。
void Array::sort(int order) //Array is a struct that contains a vector of pointers named vect, as well as this function.
{
if (order==0) return;
bool ascending = (order>0);
int i,j;
Data* buffer; //Data is a struct containing some variables, including the key that has to be sorted.
for (i=1; i<_size; i++)
{
buffer = vect[i]; //A vector of pointers to Data objects declared in the Array struct.
j=i-1;
while ( j>=0 && (ascending?(vect[j]->key > buffer->key):(vect[j]->key < buffer->key)))
{
vect[j+1] = vect[j];
j--;
}
vect[++j] = buffer;
}
}
您实际上想要编写两个函数,每个函数静态地(即在编译时)知道其排序顺序,并选择动态调用哪一个。
最简单的改变是:
// original code, templated
template <bool Ascending>
void Array::sort() {
int i,j;
Data* buffer;
for (i=1; i<_size; i++) {
buffer = vect[i];
j=i-1;
while (j>=0 && (Ascending?(vect[j]->key > buffer->key):(vect[j]->key < buffer->key)))
{
vect[j+1] = vect[j];
j--;
}
vect[++j] = buffer;
}
}
// original prototype
void Array::sort(int order) {
if (order > 0)
sort<true>();
else if (order < 0)
sort<false>;
}
注意,尽管内部循环中仍然有一个三元语句,但由于Ascending
是常数(在每个实例化中只是一个不同的常数),因此可以很容易地对其进行优化。
更干净的方法是完全删除三元语句,并将某种比较函数传递到内部函数模板中。我们可以传递一个函数指针,或者一个lambda——我使用内置的函数对象,因为它们已经做了我们想要的事情。
// Comparitor is some type you can call to compare two arguments
template <typename Comparitor>
void Array::sort(Comparitor comp) {
int i,j;
Data* buffer;
for (i=1; i<_size; i++) {
buffer = vect[i];
j=i-1;
while (j>=0 && comp(vect[j]->key, buffer->key)) {
vect[j+1] = vect[j];
j--;
}
vect[++j] = buffer;
}
}
// std::greater and less come from <functional>
void Array::sort(int order) {
typedef decltype(vect[0]->key) KeyType; // or use the real type directly
if (order > 0)
sort(std::greater<KeyType>());
else if (order < 0)
sort(std::less<KeyType>());
}
一个选项是使用模板,并将函数重新定义为
template<class T> void Array::sort(T op)
{
...
while ( j>=0 && op(vect[j]->key,buffer->key))
...
}
然后你可以用合适的排序对象调用你的排序
struct LessThan : public std::binary_function<int, int, bool> {
bool operator() (int x, int y) const { return x < y; }
};
struct GreaterThan : public std::binary_function<int, int, bool> {
bool operator() (int x, int y) const { return x > y; }
};
Array::sort(LessThan());
如果你真的想要性能,你可以写两个函数,而不是一个。但会导致重复。这就是C++在模板方面大放异彩的地方。
相关文章:
- 这是插入排序的正确实现吗?
- 更改运行时优先级队列的排序功能
- 使用列表 STL 递归进行插入排序
- 列表 iter 不取消引用 使用列表进行插入排序
- 如何使插入排序更快?
- 插入排序的最小交换
- 不正确的比较和交换计数器输出用于快速排序功能
- 排序功能在C++中未按预期工作
- 基于不同字段的对象向量的排序功能
- 双链表C++上的插入排序
- 如何在插入排序中使用 replace() 使语句变得不必要
- 如何将标准::矢量插入具有自定义排序功能的 std::set 中
- C++插入排序错误功能不起作用
- 如何在不通过插入排序更改原始矢量的情况下对 2D 矢量进行排序
- 插入排序打印错误的输出
- 从矢量末尾开始的插入排序
- 插入排序:我做错了什么?
- 插入排序的向量<unique_ptr<对时避免堆分配<>>>
- 获取有趣的输出以进行插入排序
- 带顺序开关的插入排序功能