SPL数据结构2-Heap,最大堆,最小堆
Posted tim_xiao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPL数据结构2-Heap,最大堆,最小堆相关的知识,希望对你有一定的参考价值。
堆是一种常见的数据结构。其底层就是一个用数组实现的二叉树。但是没有父指针和子指针。 根据堆属性来进行排序。分为最小堆和最大堆。
- 最小堆:父节点的值比每个子节点的值都要小
- 最大堆:父节点的值比每一个子节点的值都要大
一般应用在以下场景:
- 快速排序(取最大值 最小值)
- 优先队列
最大堆/最小堆
spl中SplHeap抽象类实现了堆数据结构。SplMaxHeap和SplMinHeap继承自SplHeap,分别用来实现最大堆和最小堆。以下代码以最大堆为例做说明,最小堆的时候和最大堆类似
// 最大堆
$maxheap = new SplMaxHeap();
// 插入节点并重建堆
$maxheap->insert(12);
$maxheap->insert(3);
$maxheap->insert(222);
$maxheap->insert(2);
$maxheap->insert(312);
$maxheap->insert(3);
$maxheap->insert(13);
$maxheap->insert(32);
$maxheap->insert(3);
$maxheap->insert(1);
echo "最大推顶层元素:" . $maxheap->top() . php_EOL;
// extract提取顶层元素
// 取出节点并重建堆
echo "extract:" . $maxheap->extract() . PHP_EOL;
echo "extract:" . $maxheap->extract() . PHP_EOL;
echo "extract:" . $maxheap->extract() . PHP_EOL;
echo "判断是否是空堆:" . PHP_EOL;
var_dump($maxheap->isEmpty());
// 当堆长度为0 的时候该堆为空堆
echo "当前堆长度:" . $maxheap->count() . PHP_EOL;
实现自定义推排序
很多时候,单纯的数字大小比较不能满足我们对于堆数据结构的要求。比如我们要基复杂数组实现堆排序。SplHeap 类提供了compare抽象方法,只要我们实现自己的compare方法,就可以对任意数据类型进行最小堆最大堆排序
class MmaxHead extends SplHeap
{
/**
* 假设推中为关联数组 保存学生信息 根据成绩排名
* [\'name\'=>\'Bob\',score=>99.2]
*
* @param mixed $value1
* @param mixed $value2
*
* @return int
*/
protected function compare($value1, $value2)
{
if ($value1[\'score\'] > $value2[\'score\']) {
return 1;
} elseif ($value1[\'score\'] < $value2[\'score\']) {
return -1;
} else {
return 0;
}
}
}
$myheap = new MmaxHead();
$myheap->insert([\'name\' => "bob1", "score" => 65]);
$myheap->insert([\'name\' => "bob2", "score" => 34.3]);
$myheap->insert([\'name\' => "bob3", "score" => 99.3]);
$myheap->insert([\'name\' => "bob4", "score" => 23.4]);
$myheap->insert([\'name\' => "bob5", "score" => 55]);
$myheap->insert([\'name\' => "bob6", "score" => 66]);
echo "成绩最高的是" . PHP_EOL;
var_dump($myheap->top());
echo "依次排名:" . PHP_EOL;
while (!$myheap->isEmpty()) {
var_dump($myheap->extract());
}
优先队列
spl中已经为我们提供了优先队列SplPriorityQueue。SplPriorityQueue基于最大堆实现,即优先级越大越先出队。可以通过重写compare改为优先级小先出队(最小堆),同样也可以通过集成重写compare来实现自己的业务逻辑
$objPQ = new SplPriorityQueue();
$objPQ->insert(\'A\',3);
$objPQ->insert(\'B\',6);
$objPQ->insert(\'C\',1);
$objPQ->insert(\'D\',2);
echo "优先队列长度: ".$objPQ->count().PHP_EOL;
/**
* 设置元素出队模式
* SplPriorityQueue::EXTR_DATA 仅提取值
* SplPriorityQueue::EXTR_PRIORITY 仅提取优先级
* SplPriorityQueue::EXTR_BOTH 提取数组包含值和优先级
*/
// 默认
$objPQ->setExtractFlags(SplPriorityQueue::EXTR_DATA);
echo "top 提取值: ".$objPQ->top().PHP_EOL;
$objPQ->setExtractFlags(SplPriorityQueue::EXTR_PRIORITY);
echo "top 提取优先级: ".$objPQ->top().PHP_EOL;
$objPQ->setExtractFlags(SplPriorityQueue::EXTR_BOTH);
echo "top 返回数组 包括值和优先级: ".PHP_EOL;
var_dump($objPQ->top());
//遍历:
$objPQ->setExtractFlags(SplPriorityQueue::EXTR_DATA);
while($objPQ->valid()){
print_r($objPQ->current());
$objPQ->next();
}
上一篇:双向链表,堆栈,队列
下一篇:SPL 数据结构3-SplFixedArray
以上是关于SPL数据结构2-Heap,最大堆,最小堆的主要内容,如果未能解决你的问题,请参考以下文章