堆(优先级队列)的比较运算与快速排序默认cmp函数的区别

在写快排的cmp函数的时候,return left>right 就是从大到小,return left 就是从小到大。堆的比较运算在建堆时是如何应用的,为什么左大于右就会建立小顶堆,右大于左反而建立大顶堆?

(优先级队列的定义正好反过来了。估计是底层实现上优先队列队首指向后面,队尾指向最前面的缘故)

答:这个问题主要涉及到堆排序的过程,比较操作在建堆过程中的应用

​ 在快速排序中,我们确实可以通过更改比较函数cmp(return left>right 代表降序排序,return left 代表升序排序)来改变排序的方向。例如,sort函数里面

//从大到小排序需要加的参数 
sort(a.begin(),a.end(),greater<int>());

但在堆排序中,情况稍有不同。

​ 在建堆过程中,我们需要维护堆的性质。当我们说 "左大于右就会建立小顶堆,右大于左反而建立大顶堆"时,实际上我们是在描述父节点和子节点之间的比较操作

假设我们有两个元素 left 和 right,其中 left 是父节点,right 是其中一个子节点:

  • 在建立小顶堆的过程中,我们需要保证父节点的值小于或等于子节点的值。如果父节点的值大于子节点的值(即 left > right我们就需要交换这两个元素,使得父节点的值小于或等于子节点的值,从而维持堆的性质。
//小顶堆,较小的元素放在堆顶部
 priority_queue<int, vector<int>, greater<int>> min_heap;
  • 在建立大顶堆的过程中,我们需要保证父节点的值大于或等于子节点的值。如果父节点的值小于子节点的值(即 left < right我们就需要交换这两个元素,使得父节点的值大于或等于子节点的值,从而维持堆的性质。
//大顶堆,较大的元素放在堆顶
priority_queue<int, vector<int>, less<int>> max_heap;

所以,在堆排序中,我们是通过比较和可能的交换来维持堆的性质,而不是像快速排序那样直接通过比较函数来改变排序的方向。这就是为什么在建堆过程中,“左大于右就会建立小顶堆,右大于左反而建立大顶堆”。

你可能感兴趣的:(算法,数据结构,c++)