Pagini recente » Cod sursa (job #1723178) | Cod sursa (job #2241587) | Cod sursa (job #1727033) | Cod sursa (job #2959289) | Cod sursa (job #2460184)
#include <fstream>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <functional>
constexpr auto SMALL_SORT_THRESHOLD = 500;
void make_heap(std::vector<uint32_t>& v, uint32_t fst, uint32_t lst)
{
const auto size = lst - fst;
if (size <= 1) {
return;
}
if ((size == 2)) {
std::swap(v[fst], v[fst + (v[fst] > v[fst + 1])]);
return;
}
for (auto i = size / 2; i >= 1; --i) {
for (auto j = i; j <= (size / 2);) {
const auto leftIdx = j * 2;
const auto rightIdx = leftIdx + 1;
std::reference_wrapper<uint32_t> leftChild = std::ref(v[leftIdx + fst - 1]);
std::reference_wrapper<uint32_t> rightChild = std::ref(v[rightIdx + fst - 1]);
auto bestIdx = j;
std::reference_wrapper<uint32_t> best = std::ref(v[j + fst - 1]);
std::reference_wrapper<uint32_t> curr = best;
if (leftChild < best) {
bestIdx = leftIdx;
best = leftChild;
}
if (rightChild < best) {
bestIdx = rightIdx;
best = rightChild;
}
if (bestIdx == j)
break;
std::swap(best.get(), curr.get());
j = bestIdx;
}
}
if (size & 1) {
for (auto idx = size; idx > 1; idx /= 2) {
auto currentIdx = idx + fst - 1;
auto parentIdx = idx / 2 + fst - 1;
if (v[currentIdx] < v[parentIdx]) {
std::swap(v[currentIdx], v[parentIdx]);
} else {
return;
}
}
}
}
void small_sort(std::vector<uint32_t>& v, uint32_t fst, uint32_t lst)
{
// Make a heap, then use selection sort
make_heap(v, fst, lst + 1);
for (size_t i = fst + 2; i <= lst; ++i) {
uint32_t bubble = v[i];
uint32_t right = i;
uint32_t left = right;
while (v[--left] > bubble)
{
v[right--] = v[left];
}
v[right] = bubble;
}
}
void qsort(std::vector<uint32_t>& v, uint32_t left, uint32_t right) {
if (right <= left)
return;
if ((right - left + 1) <= SMALL_SORT_THRESHOLD) {
small_sort(v, left, right);
return;
}
const auto mid = (left + right) / 2;
const auto rnd = left + rand() % (right - left);
std::swap(v[mid], v[rnd]);
const auto pivot = v[mid];
auto i1 = left;
auto i2 = right;
while (true) {
while((v[i1] < pivot)) ++i1;
while((v[i2] > pivot)) --i2;
if (i1 <= i2) {
std::swap(v[i1], v[i2]);
++i1;
--i2;
} else {
break;
}
}
qsort(v, left, i2);
qsort(v, i1, right);
}
int main()
{
std::srand(std::time(nullptr));
std::ifstream fin("algsort.in");
std::ofstream fout("algsort.out");
std::vector<uint32_t> v;
uint32_t n;
fin >> n;
v.reserve(n);
for (uint32_t i = 0; i < n; ++i) {
uint32_t x;
fin >> x;
v.push_back(x);
}
qsort(v, 0, v.size() - 1);
for (const auto x : v) {
fout << x << " ";
}
return 0;
}