堆排序(怎么构造堆,在堆排序过程中的比较方法)

堆排序(如何构造堆,在堆排序过程中的比较方法)
题目:无序序列{59,11,26,34,17,91,25},要用堆排序得到{11,17,25},共执行多少次比较?

我的问题是:如何从无序序列构造堆?
我用的是清华严蔚敏的教材,上面说:'从一个无序序列建堆的过程就是一个反复"筛选"的过程.'
而从书上又可以了解到"筛选"是作用于二叉树的操作,这棵二叉树是从哪来的呢,书上给的例子也是直接就有一棵二叉树,这点我不太理解.如果说这棵二叉树是通过一定的规则构造的,那么我的问题是:如何从一组无序序列构造堆所对应的二叉树呢?

就以上面的无序序列作为例子吧.

------解决方案--------------------
通过建堆算法。
也就是建立你说的“书上给的例子也是直接就有一棵二叉树”的那棵二叉树。这是堆排序的先决条件。只有无序序列已经是堆了,用堆排序算法才可以起到排序的效果。建堆算法应该在前面已经出现了,所以作者才直接给出了无序序列的堆形式(也就是那棵二叉树)。
------解决方案--------------------
C/C++ code
#define PARENT(i)  ((i) / 2)
#define LEFT(i)    ((i) * 2)
#define RIGHT(i)   ((i) * 2 + 1)
#define RELOCAL(i) ((i) - 1)
template <class T>
void MaxHeapify(T *array,const size_t length,const size_t i)
{
    if (NULL == array || length == 0 || 0 == i || i > length)
    {
        return;
    }
    if (LEFT(i) <= length)
    {
        if(array[RELOCAL(i)] < array[RELOCAL(LEFT(i))])
        {
            Swap(array[RELOCAL(i)],array[RELOCAL(LEFT(i))]);
        }
    }
    if (RIGHT(i) <= length)
    {
        if (array[RELOCAL(i)] < array[RELOCAL(RIGHT(i))])
        {
            Swap(array[RELOCAL(i)],array[RELOCAL(RIGHT(i))]);
        }
    }
    MaxHeapify(array,length,LEFT(i));
    MaxHeapify(array,length,RIGHT(i));
    return;
}
template <class T>
void BuildMaxHeap(T *array,const size_t length)
{
    if (array == NULL || length <= 1) 
    {
        return;
    }
    size_t i = length/2;
    while (i != 0)
    {
        MaxHeapify(array,length,i);
        --i;
    }
    return;
}
template <class T>
void HeapSort(T *array,const size_t length)
{
    if (array == NULL || length <= 1)
    {
        return;
    }
    BuildMaxHeap(array,length);
    size_t  l = length;
    while (l != 0)
    {
        swap(array[0],array[RELOCAL(l)]);
        --l;
        MaxHeapify(array,l,1);
    }
    return;
}

------解决方案--------------------
debug.h
C/C++ code

class OutOfBounds
{
};

------解决方案--------------------
建堆思想:
首先将无序序列一次作为一个完全二叉树存储,也就是你上面的例子中59作为根,依次11,26作为孩子节点等等延续。
然后从第n/2个节点开始,一直到第一个节点59,进行堆的调整,这个过程叫建堆。

如果是大根堆,那么第一个元素就是最大的节点,取出最大节点和最后一个节点元素交换,然后堆的大小相应减1,然后从根开始调整堆!!