我们必须知道如何使用堆排序。我无法理解一件事:当我们构建一个堆时,为什么循环中使用的大小除以2(声明为计数器" i")?下面显示了代码。如果有人向我解释,我将非常感激。
// heap
void heapify (int tab[], int o, int heapsize)
{
int l = 2 * o + 1;
int r = l + 1;
int largest;
if (l <= heapsize && tab[o] > tab[l])
largest = l;
else
largest = o;
if (r <= heapsize && tab[largest] > tab[r])
largest = r;
if (largest != o)
{
swap(tab[o], tab[largest]);
heapify(tab, largest, heapsize);
}
}
void build_heap(int tab[], int heapsize)
{
for (int i = heapsize/2; i >= 0; i--)
heapify(tab, i, heapsize);
}
void heap_sort(int tab[], int size)
{
int heapsize = size;
build_heap(tab, heapsize);
do{
swap(tab[0], tab[heapsize]);
heapify(tab, 0, heapsize - 1);
heapsize--;
} while (heapsize > 0);
}
答案 0 :(得分:1)
我认为你的意思是
for (int i = heapsize/2; i >= 0; i--)
嗯,发生的事情是这样的。但首先,这里有一堆小费。你必须经常在两种思考堆的方式之间切换:一个连续的数组和一个树。
因此,如果您查看heapify
,您可以在数组表示中看到对于索引i
,代码会考虑l
和r
2 * i
}和2 * i +
。在树表示中,这些是左右孩子。
现在在堆表示中,heapsize / 2
是什么?它是倒数第二行的一部分,实际上有孩子。这些孩子将被heapify
函数考虑(我们刚刚看到)。没有必要从右边开始,因为没有孩子可以比较。