堆排序中的上滤和下滤
这两个地方搞了好多次,每次做题的时候都容易忘记,现在把其特点记下来。
首先是下滤,就是把当前节点向下寻找其应该在的位置,它要求当前节点的左右子节点都满足堆的性质。最多的应用在堆排序的过程中:每次把最大堆的第一个节点(最大)和当前排序队列的最后一个元素交换,这样当前最大值就去了该去的地方,再对当前首元素进行下滤。其次还有删除节点。
其次是上滤,这就是把当前节点向上寻找其该在的位置。重点是明白它的要求是必须保证当前节点以及是个最大,最小堆。要不然,如果当前节点和这个节点的全部子节点形成的队列不是个最大,最小堆得话,上滤是没有意义的,因为并没有把真正最大,最小的元素“滤”上去。它最多的应用是插入节点。
构造堆得过程有2种方式。
1,循环每一个无序元素,把它插入到最大堆得末尾然后上滤。
2,直接从最后一个非叶子节点的元素开始往根节点下滤。
这里第一种方式没啥可以说的。主要是第二种。我也不知道问什么每次做题都要一愣,甚至好几次没做出来。看来还是理解不深。
首先为什么要从倒数第一个非叶子节点开始。首先对于叶子节点,明显下滤是没有意义的,因为没有子节点下滤当然还是不变。其次解释为什么要从后往前。这里要真的明白下滤的意义。下滤的要求是当前节点的左节点和右节点都已经是最大堆了。那么如果从根节点开始下滤,它怎么保证这一点呢?所以必须从第一个有意义的节点(也就是倒数第一个非叶子节点)开始,从后往前下滤,每次下滤的时候因为前面下滤过了,可以保证当前下滤的时候,当前节点的左右子节点都是最大堆。到最后根节点当然就让整个队列都变成最大堆了。