Куча сортировки не работает или неправильный расчет

Функция max-heap работает нормально, но heapsort не работает.

Когда я запускаю этот код. показывает неверный расчет.

Your input is:
9 79 42 86 33 75

Your max-heap is:
86 79 42 75 33 9

Ascending numerical order:
86 79 42 75 33 9

Как вы можете видеть в моем последнем выводе, числовой порядок по возрастанию имеет то же значение, что и max-heap, но это не то, что я ожидаю.

Моя задача состоит в том, что я должен отсортировать число из максимальной кучи. Кроме того, мне нужно поменять местами первый и последний элемент из массива максимальной кучи, а затем игнорировать последний элемент. Кроме того, как только последний элемент будет проигнорирован, мне придется снова выполнить функцию max-heap.

Пример того, как работает расчет. max-heap: 86, 79, 42, 75, 33, 9. В разделе сортировки я должен поменять местами первый и последний элемент, а затем игнорировать последний элемент, поэтому результат сортировки кучи должен быть: 9, 79, 42 , 75, 33, [86] (квадратные скобки означают игнорирование или удаление). Я должен снова сделать max-heap из предыдущей сортировки. Второй результат максимальной кучи будет 79, 75, 9, 42, 33. когда я вернусь к сортировке, мне нужно поменять местами первый и последний элемент, а затем снова игнорировать последний элемент, поэтому максимальная куча равна 79, 75 , 9, 42, 33, а результат сортировки в куче должен быть: 33, 75, 9, 42, [79], [86]. Я должен сделать тот же шаг снова и снова, пока все числа не будут отсортированы.

Пример вывода, который я хочу отобразить:

Мой ввод 9, 79, 42, 86, 33, 75

Максимальная куча должна быть: 86, 79, 42, 75, 33, 9.

По возрастанию число должно быть: 9, 33, 42, 75, 79, 86.

Дополнительные примеры см. на веб-сайте https://en.wikipedia.org/wiki/Heapsort#Example, См. пример 2 — Сортировка

А вот код неправильного расчета:

#include "stdafx.h"
#include <iostream>

using namespace std;

int heap[30];

void main()
{
int n, index, parent, flag, dummy;
n = 7; //size of table

// user input number
for (index = 1; index < 7; index++) 
{
    cout << "Enter value " << index << ": ";
    cin >> heap[index];
}

// output for user element
cout << "\nYour input is:\n";
for (index = 1; index < 7; index++) 
{
    cout << heap[index] << " ";
}

flag = 1;

while (flag == 1)
{
    flag = 0;

    //heapify
    for (index = 7; index >1; index--)
    {
        parent = index / 2;
        if (heap[parent] < heap[index])
        {
            dummy = heap[parent];
            heap[parent] = heap[index];
            heap[index] = dummy;
            flag = 1;
        }

        // Sorting --> swap first and last of the array and then ignore the 
        //last array and reheap from above until all number sorted.

        while (heap[0] >= 1)
        {
            int last = heap[0];
            int temp1 = heap[1];
            heap[1] = heap[last - 1];
            heap[last - 1] = temp1;
            heap[0]--;
        }
    }
}

cout << "\n\nYour max-heap is:\n";
for (index = 1; index < 7; index++) // output for after heap
{
    cout << heap[index] << " ";
}

cout << "\n\nAscending numerical order:\n";
for (index = 1; index < 7; index++) //output for sorting.
{
    cout << heap[index] << " ";
}

getchar();
getchar();
}

Также код, который я не могу изменить или заменить, который

    while (flag == 1)
{
    flag = 0;

    //heapify
    for (index = 6; index >1; index--)
    {
        parent = index / 2;
        if (heap[parent] < heap[index])
        {
            dummy = heap[parent];
            heap[parent] = heap[index];
            heap[index] = dummy;
            flag = 1;
        }
    }

}

person Sam    schedule 09.05.2018    source источник
comment
Скорее всего, вы делаете это для практики, но если вам когда-нибудь понадобится куча в реальном мире, взгляните на std::make_heap и связанные с ним функции.   -  person hlt    schedule 10.05.2018
comment
- Хит, Это не практика. Кроме того, я не могу изменить код функции кучи из приведенного выше, который предназначен для (index = 7; index ›1; index--) { parent = index/2; если (куча [родительский] ‹ куча [индекс]) { фиктивный = куча [родительский]; куча[родительский] = куча[индекс]; куча [индекс] = фиктивный; флаг = 1; } И это моя задача, только мне нужно добавить сортировку с помощью кучи   -  person Sam    schedule 10.05.2018
comment
Я новичок здесь, мне жаль, что я не знаю, как отобразить код в этом комментарии. Кроме того, я хочу добавить новую строку, и я нажимаю клавишу ввода, но это заставляет мой комментарий быть отправленным.   -  person Sam    schedule 10.05.2018
comment
Форматирование кода в комментариях работает с использованием обратных кавычек (`code`), но не на нескольких строках. Вы также должны убрать часть сортировки из части heapify — сделайте это после того, как вы напечатаете кучу, иначе вы получите странное несогласованное состояние. Только тогда мы сможем увидеть, действительно ли ваш код работает.   -  person hlt    schedule 10.05.2018
comment
Как правило, лучше отредактировать первоначальный вопрос, чтобы добавить информацию, а не помещать ее в комментарии.   -  person user4581301    schedule 10.05.2018
comment
Я беру часть сортировки из heapify и помещаю ее после печати max-heap. Я тестирую его, и результат та же проблема. И спасибо, что подсказали, как это сделать.   -  person Sam    schedule 10.05.2018
comment
Я пытаюсь форматировать код, но не работает   -  person Sam    schedule 10.05.2018
comment
@ user4581301 это хорошая идея, но как мне отредактировать вопрос?   -  person Sam    schedule 10.05.2018
comment
Используйте ссылку редактирования под вопросом   -  person user4581301    schedule 10.05.2018
comment
@Sam Итак, вы написали код, вы знаете, что этот код должен делать, но он не делает то, что вы хотите. Итак, какую отладку вы сделали? Использовали ли вы отладчик для пошагового выполнения программы, чтобы увидеть, где она отклоняется от вашего плана?   -  person PaulMcKenzie    schedule 10.05.2018
comment
@PaulMcKenzie Нет этого кода от моего учителя, и я должен добавить утверждение, что число сортировки с помощью пирамидальной сортировки. И я пробовал отладчик, но я до сих пор не понимаю, как он работает.   -  person Sam    schedule 10.05.2018


Ответы (1)


У вас много ошибок в коде.

Первый, который я заметил, находится в вашем цикле while

while (heap[0] >= 1) //heap[0] = 0 since you declared your array statically
    {
        int last = heap[0]; // last = 0
        int temp1 = heap[1];
        heap[1] = heap[last - 1]; //trying to find element heap[-1] ERROR
        heap[last - 1] = temp1; //heap[-1] = heap[1]
        heap[0]--; //heap[0] = -1 why?
    }

Во-вторых, вы начинаете с индекса 1 и переходите к индексу 6 в своем входном цикле (первый цикл for в коде), но когда вы пытаетесь внести некоторую разницу в свою кучу в третьем цикле for, вы начинаете с индекса 7 и вы переходите к индексу 2.

Я не смог найти способ в вашем коде, поэтому я опубликую свой. Он следует алгоритму на той вики-странице, которую вы разместили.

#include <iostream>

using namespace std;



void build_heap(int *heap, int index)
{
    if(index>1)
    {
       int new_input = heap[index], tmp = 0;
    //since your index starts from 1 and goes up to n in heap
    //parent from index k is (k%2==1) ? (k-1)/2 : k/2
    if(index % 2 == 1)
        index--;
    if(heap[index/2] < new_input)
    {

        tmp = heap[index/2];
        heap[index/2] = new_input;
        heap[index] = tmp;
        build_heap(heap, index/2);
       }
    }
}

void make_order_in_heap(int *heap, int n)
{
if(n>1)
{
    int index = 1;
    int child_index;
    bool work = true;

    while(work && index < n)
    {
        //finding child_index
        if( index * 2 + 1 <= n)
        {
            child_index = heap[index*2] > heap[index*2+1] ? index*2 : index*2+1;
        }
        else if(index * 2 <= n)
        {
            child_index = index*2;
        }
        else
        {
            //this index has no  children
            return;
        }
        work = false;
        if(heap[child_index] > heap[index])
        {
            int tmp = heap[index];
            heap[index] = heap[child_index];
            heap[child_index] = tmp;
            index = child_index;
            work = true;
        }
    }

}
}

void swap_first_and_last(int *heap, int n)
{
if(n>1)
{
    int tmp = heap[1];
    heap[1] = heap[n];
    heap[n] = tmp;
}
}

void sort_heap(int *heap, int n)
{
if(n>1)
{
    swap_first_and_last(heap, n);
    //we swaped first and last element in heap with n elements
    //so now first element in heap of n-1 elements is not on his      possiton
    make_order_in_heap(heap, n-1);
    sort_heap(heap, n-1);
}
}

int main()
{
int heap[30];
int n, index, parent, flag, dummy;
n = 7; 

for (index = 1; index <= n; index++) 
{
    cout << "Enter value " << index << ": ";
    cin >> heap[index];
    build_heap(heap, index);
}

cout << "\nYour input is:\n";
for (index = 1; index <= n; index++) 
{
    cout << heap[index] << " ";
}


sort_heap(heap, n);

cout << "\n Sorted array is:\n";
for (index = 1; index <= n; index++) 
{
    cout << heap[index] << " ";
}
return 0;
}
person Aleksa Jovanovic    schedule 10.05.2018
comment
Это работает для меня, спасибо за вашу помощь. Кроме того, я нашел решение, я просто добавил несколько строк для heapsort без вызова какой-либо функции void. Я хотел бы поделиться своим решением с другими людьми, у которых такая же проблема, как и у меня, но, к сожалению, я не знаю, чтобы поделиться кодом в этот комментарий. :( - person Sam; 05.06.2018
comment
вы не можете написать код в комментарии, но вы можете ответить на свой вопрос - person Aleksa Jovanovic; 05.06.2018
comment
Вы можете принять или лайкнуть ответ, если он вам помог ???? - person Aleksa Jovanovic; 05.06.2018