当前位置: 首页 > 知识库问答 >
问题:

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

冀越
2023-03-14

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

读完这节课后,我在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;
   }

奇怪的是,对我来说,构建min堆-提取min(或在构建min堆后在根目录下执行min-heapify)应该按升序进行。然而,在执行此代码并打印出结果向量后,我得到:

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 

我是否做错了什么,或者我对堆/堆排序的理解不清楚?我错过了什么?

共有1个答案

奚和光
2023-03-14

是<代码>交换程序(vec[0],vec[size]) 是提取。将第一个元素提取到向量的最后一个元素。因此得到了相反的结果。

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

如果你实施类似

result.push_back(heap.pop_min());

你会得到你期待的订单。

 类似资料:
  • 我只是想看看我是否理解教授和在线资源所说的话。 对于heapSort算法,第一个元素的索引从0开始。 对于最大堆,如果子堆大于父堆,则percolate down应将最大子堆与其父堆交换,例如(这是用于赋值,因此我尝试发布尽可能少的代码): 所以最后,最大元素应该在索引0处。 如果这是正确的,我不理解的是heapSort实现: 最大堆中的渗滤层不应该将最大的元素放在索引0处吗?在这种情况下,为什么

  • 我在[17,98,89,42,67,54,89,25,38]中有一个数字列表,从左到右插入到一个空堆中。生成的堆是什么?

  • 对于堆排序,如果我们想按升序对数组排序,那么应该在最大堆还是最小堆中转换堆?

  • 我的教授介绍了如何使用ArrayList创建Max Heap类。然后他让我们写一个maxHeapSort方法。我几乎成功地将堆按降序排序,但我假设排序应该按升序。现在我使用一个最大堆为[11,5,8,3,4,1]的ArrayList,它排序为[11,8,5,3,4,1]。 这是我的maxHeapSort代码: 下面是我的教授给出的heapifyDown方法: 这是我的测试代码:

  • 我试图构造一个最大堆,当插入每个新值时,值会上移或下移到正确的位置,我还没有实现下移函数,所以现在我正在使用一个测试,该测试应该只需要程序上移。测试数据按以下顺序输入: [16, 10, 14, 9, 7, 1, 4, 2, 8, 3] 我在主类中使用以下代码在堆中插入值: 下一位代码是插入和移位的地方: 移位函数是siftUp(),我认为这就是问题所在。当程序以这些输出运行时: 但这是不正确的,

  • 我想按第三个和第一个元素对元组数组进行排序,因此我使用了以下代码: 我的问题是,在前面的例子中,我可以按第三个元素和第一个元素的升序排序,也可以按它们的降序排序(使用反向)。但是如何按第三个元素的升序和第一个元素的降序排序。 请在你的回答中考虑以下情况: 在这种情况下,我不知道内部数组的确切大小(取决于我读入该数组的文件模式),我想按侧中的所有项进行排序(一些升序和一些降序)。 编辑:看起来,我明