LINUX.ORG.RU

О сортировке пирамидой

 , ,


0

2

В книге Седжвика. «Фундаментальные алгоритмы на С++» предлагается такая сортировка:

template <class Item>
void fixDown(Item *a, int k, int N)
{
    while (2 * k <= N)
    {
        int j = 2 * k;
        if ((j < N) && (a[j] < a[j + 1]))
            j++;
        if (a[k] > a[j])
            break;
        std::swap(a[k], a[j]);
        k = j;
    }
}

template <class Item>
void heapsort(Item *a, int l, int r){
    int k, N=r-1+1;
    Item *pq = a+1-1;
    for(k=N/2;k>=1;k--)
    fixDown(pq, k, N);
    while (N>1)
    {
        std::swap(pq[1], pq[N]);
        fixDown(pq, 1, --N);
    }    
}

И всё бы хорошо, сортирует полюбому быстро за O(N lgN), памяти дополнительной не требует, но есть неприятный нюанс: Если сгенерить такой массив, такой функцией.

int len=2300000;
auto array=generantion_array(0, 23000000,len);

int *generantion_array(int min, int max, int len)
{
    std::default_random_engine generator;
    std::uniform_int_distribution<int> distribution(min, max);
    int *array = new int[len];
    for (int i = 0; i < len; i++)
    {
        array[i] = distribution(generator);
    }
    return array;
}

То получается пара элементов не отсортирована:

180 10

Почему так происходит?

★★★★★
Ответ на: комментарий от ox55ff

не скомпилируется.

Ну вместо темы «почему не сортирует» была бы тема «почему не компиляет». И вообще зависит от обстоятельств, другие имена в других языках вполне прокатят. Это уже нюансы.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от thesis

Очевидно, что те, кто понимает - умнее тех, кто не.

Не факт. Они могут иметь какие-то дополнительные знания, которых учебник в явном виде не требует, но без которых становится непонятным.

annulen ★★★★★
()

Ладно хотя бы со стековерфлоу можно нажать ctrl+c и ctrl+v, а то такая же фигня вечно была бы! Копируют, не думая. Хотя я тоже часто так делаю, когда нужна очевидная хрень с какими-нибудь криптографическим набором методов и свойств, придуманных инопланетянами. А вот в алгоритм лучше вникать

anonymous
()
Ответ на: комментарий от Reset

Нет, имена как раз всратые и наглядно продемонстрировано, что эта всратость порождает ошибки на ровном месте.

l r – можно left, right, и читать код станет гораздо легче.

Не надо писать код так, как писали 20-30-40-50 лет назад. С тех пор очень много было переосмысленно и стилю кода стали уделять сильно больше внимания.

soomrack ★★★★★
()

PS:

Седжвик книгу написал давно, и его код это просто демонстрация алгоритма в синтаксисе С++.

Не надо его код воспринимать, как полноценную реализацию алгоритма на С++. Как С++ код приведенная реализация неприемлима, т.к. в частности, есть опасность переполнения при умножении на 2.

soomrack ★★★★★
()
Ответ на: комментарий от soomrack

Как С++ код приведенная реализация неприемлима, т.к. в частности, есть опасность переполнения при умножении на 2.

В каком месте? Так можно договориться до того что с интами вообще ничего делать нельзя.

bugfixer ★★★★★
()
Последнее исправление: bugfixer (всего исправлений: 1)
Ответ на: комментарий от soomrack

очень много было переосмысленно и стилю кода

Я считаю что naming это вообще отдельное искусство: найти правильный баланс между компактностью кода, его readability и searchability не так просто, и как это формализовать - для меня загадка.

bugfixer ★★★★★
()
Ответ на: комментарий от soomrack

опасность переполнения при умножении на 2.

Есть и это даже скомпилится, но упадёт при выполнении:

auto array = new long long[3000000000];

Естественно ни в куче ни на стёке не даёт алоцировать столько памяти:

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

Даёт создать безпроблемно только такой массив булов, но в примере по сути инты.

Ygor ★★★★★
() автор топика
Последнее исправление: Ygor (всего исправлений: 1)