设想一下,如果待排元素不是一个简单的整数,而是一个庞大的结构体,移动元素的时间不能忽略不计。
元素需要频繁互换,那么移动这些元素的时间将会非常长久,效率很低
typedef very_large_item {int comparable;Tp very_large_data;
} very_large_item_collection[Nm] {};
间接排序:定义一个指针数组作为“表”(table)。
在表排序的过程中,实际上是不需要移动那些原始数据的,要移动的只是指向他们位置的那些指针。
不移动元素本身,而只移动元素本身的排序方法,我们称之为“间接排序”。
对target结构体数组进行表排序:
std::array<int, __MAX__> indices {};
std::iota(indices.begin(), indices.begin() + distance, 0);
std::sort(indices.begin(), indices.begin() + distance,
[&](auto&& i, auto&& j){return binary_cmptor(target[i], target[j]);
});for(int i {}; i < distance; ++i) visit(target[indices[i]]);
交换环:N个数字的排列由若干个独立的环组成。
在排序过程中,可能需要在不同的计算节点之间交换数据,以便进行合并或比较操作。交换环提供了一种机制,使得数据可以在节点之间以循环的方式传递,从而实现高效的通信。
#include <array>
#include <algorithm>
#include <functional>
#include <numeric>
#include <iterator>
#include <concepts>
#include <random>
#include <iostream>constexpr auto __MAX__ { static_cast<int>(1e3) };template <typename RandomIt, typename Compare = std::less<>>
void physical_sort(RandomIt first, RandomIt last, Compare comp) {using value_type = typename std::iterator_traits<RandomIt>::value_type;
/*
* static_assert(std::is_default_constructible<value_type>::value
* && std::assignable_from<value_type, value_type &&>);
*
* statements above is not neccessary:
* all declared whereat std::sort requirements and static assertions.
*/auto distance { static_cast<int>(std::distance(first, last)) };std::array<int, __MAX__> indices {};std::iota(indices.begin(), indices.begin() + distance, 0);std::sort(indices.begin(), indices.begin() + distance,[&](auto&& i, auto&& j){return comp(*(first + i), *(first + j));});for(int i {}; i < distance; ++i) {if(indices[i] == i) continue;value_type temporary {};(void) std::exchange(temporary, std::move(*(first + i)));int j { i }, previous {};while(! (indices[j] == j)) {previous = j;(void) std::exchange(*(first + j),std::move(*(first + indices[j])));std::swap(j, indices[j]);}(void) std::exchange(*(first + previous), std::move(temporary));}
}template <typename RandomIt>
void physical_sort(RandomIt first, RandomIt last) {physical_sort<RandomIt, std::less<>>(first, last, std::less<>());
}constexpr int N { 10 };
struct big_item{int key;int dummy_array[32U] {};bool operator<(const big_item& other) const & noexcept{ return key < other.key; }
} big_items[N];int main(void) {std::random_device dev;std::mt19937 gen(dev()); std::uniform_int_distribution<> distrib(0, N);std::generate(std::begin(big_items), std::end(big_items),[&]{return big_item { key: distrib(gen) };});std::puts("before");for(int i {}; i < N; ++i) std::cout << big_items[i].key << ' ';endl(std::cout);physical_sort(std::begin(big_items), std::end(big_items));std::puts("after");for(int i {}; i < N; ++i) std::cout << big_items[i].key << ' ';endl(std::cout);
}