堆的定义
n个关键字序列Kl,K2,…,Kn称为(Heap),当且仅当该序列满足如下性质(简称为堆性质):
ki<=k(2i)且ki<=k(2i+1)(1≤i≤ n),当然,这是小根堆,大根堆则换成>=号。k(i)相当于二叉树的非叶子结点,K(2i)则是左子节点,k(2i+1)是右子节点
若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:
树中任一非叶子结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。
堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,可以利用数组的特点快速定位指定索引的元素。
堆排序是一种不稳定的排序方法,平均性能O(N*logN)。
由于创建堆的时候需要比较多的比较次数,所以堆排序不适合记录较少的排序。
节点i的父节点为不大于(i/2)的最大整数
节点i的左子节点的编号为2i + 1
n个关键字序列Kl,K2,…,Kn称为(Heap),当且仅当该序列满足如下性质(简称为堆性质):
ki<=k(2i)且ki<=k(2i+1)(1≤i≤ n),当然,这是小根堆,大根堆则换成>=号。k(i)相当于二叉树的非叶子结点,K(2i)则是左子节点,k(2i+1)是右子节点
若将此序列所存储的向量R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:
树中任一非叶子结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。
堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,可以利用数组的特点快速定位指定索引的元素。
堆排序是一种不稳定的排序方法,平均性能O(N*logN)。
由于创建堆的时候需要比较多的比较次数,所以堆排序不适合记录较少的排序。
节点i的父节点为不大于(i/2)的最大整数
节点i的左子节点的编号为2i + 1
节点i的右子节点的编号为2(i+1)
// 堆排序主函数
function heapSort(&$arr)
{
initHeap($arr, 0, count($arr) - 1);
for($end = count($arr) - 1; $end > 0; --$end)
{
$temp = $arr['0'];
$arr['0'] = $arr[$end];
$arr[$end] = $temp;
ajustNodes($arr, 0, $end - 1);
}
}
// 初始化堆:根据堆的特性,建立一个堆
function initHeap(&$arr)
{
$len = count($arr);
for ($start = floor(($len - 1) / 2); $start >= 0; --$start)
{
ajustNodes(&$arr, $start, $len - 1);
}
return $arr;
}
// 调整节点:比较节点与它的子节点的大小,调换节点位置
function ajustNodes(&$arr, $start, $end)
{
$leftChild = $start * 2 + 1;
$rightChild = ($start + 1) * 2;
$maxInx = $start;
if ($leftChild <= $end)
{
if ($arr[$maxInx] < $arr[$leftChild])
{
$maxInx = $leftChild;
}
if ($rightChild <= $end && $arr[$maxInx] < $arr[$rightChild])
{
$maxInx = $rightChild;
}
if ($start != $maxInx)
{
$temp = $arr[$start];
$arr[$start] = $arr[$maxInx];
$arr[$maxInx] = $temp;
if ($end >= (2 * $maxInx + 1))
{
ajustNodes($arr, $maxInx, $end);
}
}
}
}
$arr = array(3,9,6,8,2,5,4,7,1);
heapSort($arr);
print_r($arr);