简体   繁体   中英

Heapsort Algorithm using min-heap

When I implement heapsort using a min-heap it sorts the array from largest to smallest. Is this the desired output for a heapsort using min-heap ? It seems redundant to sort again to output smallest to largest after the sort is complete since the heap itself has a smallest to largest structure.

CODE:

#include <iostream>
#include <vector>
#include "random.h"
#include "print.h"
int parent(int i)
{
    return (i - 1) / 2;
}
int left(int i)
{
    if(i == 0)
        return 1;
    else
        return 2*i;
}
int right(int i)
{   if(i == 0)
        return 2;
    else
        return 2*i + 1;
}
void min_heapify(std::vector<int> &A, int i, int heapsize)
{
    int smallest;
    int l = left(i);
    //std::cout << "left = " << l << std::endl;
    int r = right(i);
    //std::cout << "right = " << r << std::endl;
    if(l <= heapsize && A[l] < A[i])
        smallest = l;
    else
        smallest = i;
    //std::cout << "smallest = " << smallest << std::endl;
    if(r <= heapsize && A[r] < A[smallest])
        smallest = r;
    if(smallest != i) {
        print(A);
        exchange(A, i, smallest);
        min_heapify(A, smallest, heapsize);
    }
}
void build_min_heap(std::vector<int> &A)
{
    int heapsize = A.size() - 1;
    for(int i = (A.size() - 1) / 2; i >= 0; i--)
        min_heapify(A, i, heapsize);
}
void heapsort(std::vector<int> &A)
{
    int heapsize = A.size() - 1;
    build_min_heap(A);
    std::cout << "heapsort after buildmaxheap" << std::endl;
    print(A);
    for(int i = A.size() - 1; i > 0; i--) {
        exchange(A, 0, i);
        heapsize--;
        std::cout << "heapsize = " << heapsize << std::endl;
        min_heapify(A, 0, heapsize);
    }
}
int main()
{
    std::vector<int> B;
    fill(B, 5);
    print(B);
    heapsort(B);
    print(B);
    return 0;
}

Output from code:

41 65 31 41 19 
41 65 31 41 19 
41 65 19 41 31 
41 19 65 41 31 
41 19 31 41 65 
19 41 31 41 65 
heapsort after buildmaxheap
19 31 41 41 65 
heapsize = 3
65 31 41 41 19 
31 65 41 41 19 
heapsize = 2
heapsize = 1
65 41 41 31 19 
heapsize = 0
65 41 41 31 19 

Output for 20 elements:

41 65 31 41 19 15 72 11 78 69 37 23 29 63 75 4 5 49 75 99 
after buildmaxheap
4 5 15 11 19 23 29 41 31 69 37 41 72 63 75 65 78 49 75 99 
after sort
99 78 75 75 72 69 65 63 49 41 41 37 31 29 23 19 15 11 5 4 

Order : Use max-heapify to sort in asceding order, min-heapify to sort in descending order.

Sorting : Building the heap with min-heapify does not sort your array; it only enforces the (weaker) min-heap property, that is

A[parent(i)] <= A[i]

for every node i other than the root. After the heap is built, the root (leftmost position in the array) has the minimum element. Sorting then repeatedly moves elements from the root to the right and calls min-heapify on the root (bringing there the minimum of what remains), hence the descending order.

The code you are posting appears correct at a glance but does not compile as is, so I cannot test. If your array appears sorted right after building the heap, it should be a coincidence. Try a larger test.

I was just wondering about that very problem ( isn't Heap sort having an extra step at the end, the unnecessary swapping of elements. Just use min-heaps and let call min-heapify and get your work done).

Regarding this way, we could have achieved O(logn) time which somewhat disqualifies the binary decision tree model - which says O(nlogn) is acceptable tightest upper bound on comparison sorting algorithms.

The short answer is: heap data structure aren't binary search trees . A heap may guarantee ordering of elements in sorted top->bottom way, but a binary search tree guarantees they'll be ordered left to right as well. We were just mixing up binary trees and heaps.

A min heap only guarantees ,

Amin[Parent]<=A[either_of_the_children] // says nothing about ordering of children

Here is a binary tree (although unbalanced and not sorted) :

二叉树

And here is a Heap :

最小堆

Hope you get my point. If still not, then think of it as, a min heap represented an array guarantees that parent is smaller than its child, but says nothing about are all children arranged in sorted order left to right? We'll still be performing min-heapify on each child of current root to be swapped.

Normally you use a max-heap to sort in ascending order, because its easier. Using a max-heap, you 'float' the max to the front, and build the sorted list from the back.

If you want to use a min-heap to sort in ascending order, you have to build it backwards. (ie the lowest is the last index ). Otherwise you will be churning your heap.

start 18 70 6 13 12 55 
min-heap(backwards) -> 18 70 55 13 12 6
then
swap  6 w 18 -> 6, 70 55 13 12 18 -> sink 18 -> 70 55 13 18 12
swap 12 w 70 -> 6 12, 55 13 18 70 -> sink 70 -> 55 70 18 13
swap 13 w 55 -> 6 12 13, 70 18 55 -> sink 55 -> 70 55 18
swap 18 w 70 -> 6 12 13 18, 55 70 -> sink 70 -> 70 55
swap 55 w 70 -> 6 12 13 18 55, 70 
done

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM