这种排序算法已经存在吗?

时间:2018-06-29 12:26:29

标签: c++ algorithm sorting search binary

#include <iostream>
#include <vector>

using namespace std;

int main() {
  vector<int> arr;
  for (int i = 1; i <= 1000; i++)
    arr.push_back(rand() % 100000);

  //algorithm ----
  vector<int> sorted;
  sorted.push_back(arr[0]);
  for (int i = 1; i < arr.size(); ++i) {
    //case: element is smaller than the smallest sorted element
    if (arr[i] < sorted[0]) {
      sorted.insert(sorted.begin(), arr[i]);
      continue;
    }
    //case: element is inside the sorted elements, search where
    if (arr[i] < sorted[sorted.size() - 1]) {

      //linear search, really slow
      // for (int j = 0; j < sorted.size() - 1; ++j) {
      //     if (sorted[j] < arr[i] && arr[i] < sorted[j + 1]) {
      //         sorted.insert(sorted.begin() + j, arr[i]);
      //     }
      // }

      //binary search
      int low, mid, high;
      low = 0;
      high = sorted.size() - 2;
      while (low <= high) {
        mid = (low + high) / 2;
        if ( (sorted[mid] < arr[i] && arr[i] < sorted[mid + 1]) 
          || sorted[mid] == arr[i] 
          || sorted[mid + 1] == arr[i]) {
          sorted.insert(sorted.begin() + mid, arr[i]);
          break;
        }
        if (sorted[mid] < arr[i])
          low = mid + 1;
        else
          high = mid - 1;
      }
      if (low > high) {
        for (auto x : sorted)
          cout << x << " ";
        cout << "\nsomething broke!\n";
      }
    }
    //case: the element is larger than the largest sorted element
    //goes to the end
    else {
      sorted.push_back(arr[i]);
    }
  }
  //----

  for(auto x : sorted)
    cout << x << " ";
  cout << "\n";
  return 0;
}

前几天,我想到了实现二进制搜索的排序算法,这是c ++ 11中的代码。

我的问题是有人已经制定了这样的算法,或者这甚至是可用的算法吗?

我认为它在O(n Log n)附近,但是我不知道insert和push_back函数的复杂性是什么。

感谢您的帮助。 ;)

我还将线性搜索的版本包括在内,它可能更容易理解,但速度却很慢。

2 个答案:

答案 0 :(得分:3)

我会说这是插入排序的(也许是经过重新发明的)版本。 看到这个:

Insertion Sort on Wikipedia

答案 1 :(得分:0)

您的代码很像这样

if (arr.size() < 2)
  return arr;
for (auto i = std::next(arr.begin()); i != arr.end(); ++i) {
    std::rotate(std::upper_bound(arr.begin(), i, *i), i, i+1);
}

进行就地插入排序,即O(N²)。

现在让我们看看您的贡献

if (arr.size() < 2)
  return arr;
for (auto i = std::next(arr.begin()); i != arr.end(); ++i) {
    if (*i < *arr.begin())
      std::rotate(arr.begin(), i, i+1);
    else 
      if (*i > *std::prev(i)) // already in the right spot
        continue;
    std::rotate(std::upper_bound(arr.begin(), i, *i), i, i+1);
}

因此,值得的是,每次if正确时,我们都得到std::upper_bound的成本,即log N,因此情况并非如此,因此得到2 if的成本。因此,在随机排序的列表中,if的帮助会迅速减少,因为每个列表的1 / n都会迅速减少,在排序几乎是列表或排序反向的列表中,您将赢得一些,但在所有其他情况下,这只是浪费时间。