堆排序-使用哪个堆(最小/最大)进行升序排序和降序排序

heap sort - which heap (min/max) to use for ascending and descending order sort?

本文关键字:排序 最大 升序 降序 最小 堆排序      更新时间:2023-10-16

我注意到一件非常奇怪的事情。

在完成这个讲座之后,我在c++中实现了堆排序的一些代码。

代码如下。

    template<typename T> void min_heapify(std::vector<T> &vec, int i, int size)
    {
        int left  = (2*i); //left child of a zero-indexed heap (array)
        int right = (2*i)+1; //right child.
        int min;
        min = ( (left<size) && (vec[left] < vec[i]) ) ? left : i;
        min = ( (right<size) && (vec[right] < vec[min]) ) ? right : min;
        if (min!= i)
        {
            swapper(vec[i],vec[min]);
            min_heapify(vec, min, size);
        }
    }
    template<typename T> void build_min_heap(std::vector<T> &vec, int size)
    {
        int i = size/2;
        while(i--)
        {
            min_heapify(vec, i, size);
        }
    }
    template<typename T> void heap_sort(std::vector<T> &vec, int size)
    {
        // build min heap
        build_min_heap(vec, size);
        // then extract min repeatedly.
        while(size>0)
        {
            size--;
            swapper(vec[0],vec[size]);
            min_heapify(vec,0,size);
        }
    }
   int main()
   {
        vector<int> v{14,-1,1000, -999, 3,2,5,10};
        heap_sort(v, v.size());
        return 0;
   }

奇怪的是,对我来说是有意义的-建立最小堆-提取最小值(或在构建最小堆后在根执行最小堆积)结果应该是升序。然而,在执行这段代码并打印出结果向量之后,我得到:

1000 14 10 5 3 2 -1 -999 

试图弄清楚发生了什么,我改变了

min = ( (left<size) && (vec[left] < vec[i]) ) ? left : i;
min = ( (right<size) && (vec[right] < vec[min]) ) ? right : min;

min = ( (left<size) && (vec[left] > vec[i]) ) ? left : i;
min = ( (right<size) && (vec[right] > vec[min]) ) ? right : min;

,它实际上最终选择父节点和子节点中较大的(或最大值),结果向量是:

-999 -1 2 3 5 10 14 1000 

是我做错了什么,还是我对堆/堆排序的理解不清楚?我遗漏了什么?

是的,swapper(vec[0],vec[size]);是提取。将第一个元素提取到向量的最后一个元素中。因此得到了相反的结果。

堆的最小元素是vec[0]。将其交换到最后一个位置将在该向量中创建一个从最大值到最小值的排序。

如果你实现像

这样的东西
result.push_back(heap.pop_min());