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

Does this sort algorithm already exists?

本文关键字:存在 排序 算法      更新时间:2023-10-16
#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 n 附近(,但我不知道插入和push_back函数的复杂性是什么。

任何帮助,不胜感激。 ;)

我还包含了线性搜索的版本,它可能更容易理解,但真的很慢。

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

维基百科上的插入排序

你的代码在很长的时候就是这样

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);
}

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