簡體   English   中英

帶順序開關的插入排序功能

[英]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 ++帶有模板的地方。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM