优先队列其实就是一个最大堆,主要是对最大堆的操作上的一些调整

 1 <?php
 2      #最大优先队列的实现
 3  
 4      #交换函数
 5      function swap(&$arr, $inx1, $inx2) {
 6          $temp = $arr[$inx1];
 7          $arr[$inx1] = $arr[$inx2];
 8          $arr[$inx2] = $temp;
 9      }
10      
11      #最大堆节点下沉调整
12      #@param $arr 待调整数组
13      #@param $start 待调整数组的开始坐标
14      #@param $end 待调整数组的结束坐标
15      function max_heapify(&$arr, $start, $end) {
16          $max_inx = $start;
17  
18          $left_inx = ($start + 1) * 2 - 1; #左孩子坐标
19          $rig_inx = $left_inx + 1; #右孩子坐标
20  
21          if ($left_inx <= $end) { #如果存在左孩子,开始调整
22              if ($arr[$left_inx] > $arr[$max_inx]) {
23                  $max_inx = $left_inx;
24              }
25  
26              if($rig_inx <= $end && $arr[$rig_inx] > $arr[$max_inx]) { #只有拥有左孩子才调整右孩子
27                  $max_inx = $rig_inx;
28              }
29          }
30  
31          if ($max_inx != $start) {
32              swap($arr, $max_inx, $start);
33              max_heapify($arr, $max_inx, $end);
34          }
35      }
36  
37      #建立最大堆
38      function build_max_heap(&$arr) {
39          for ($i = floor(count($arr) / 2) - 1; $i >= 0; $i--) { #从最后一个非叶子节点开始调整数组,构建最大堆
40              max_heapify($arr, $i, count($arr) - 1);
41          }
42      }
43  
44      #取出最大元素并删除
45      function heap_extract_max(&$arr) {
46          $len = count($arr);
47          swap($arr, 0, $len - 1); #首尾交换
48  
49          #保持最大堆性质
50          $max = array_pop($arr);
51          max_heapify($arr, 0, $len - 2);
52          return $max;
53      }      
54  
55      #插入一个比原值大的元素或插入一个新元素到队列
56      #@param $heap 待插入堆
57      #@param $inx 待插入坐标
58      #@param $key 待插入值
59      function heap_increase_key(&$heap, $inx, $key) {
60          if ($inx >= count($heap)) {
61              $heap[] = $key;
62              $inx = count($heap) - 1;
63          } else if ($heap[$inx] >= $key) {
64              die("必须插入比原值大的Key");
65          } else {
66              $heap[$inx] = $key;
67          }
68  
69          #开始调整节点,从插入值与其父母比较,如果比父母大,则上浮插入元素,直到比较到堆顶,否则退出比较
70          while (($p = floor($inx / 2)) >= 0) {
71              if ($heap[$p] < $heap[$inx]) {
72                  swap($heap, $p, $inx);
73                  $inx = $p;
74              } else {
75                  break;
76              }
77          }
78      }
79  
80  
81      $arr = array(1, 5, 7, 4, 2);
82      build_max_heap($arr);
83      print_r($arr);
84      echo "<br>";
85      heap_extract_max($arr);
86      print_r($arr);
87      echo "<br>";
88      heap_increase_key($arr, 3, 10);
89      print_r($arr);
90      echo "<br>";
91      heap_increase_key($arr, 10, 9);
92      print_r($arr);
93  ?>

 

Array ( [0] => 7 [1] => 5 [2] => 1 [3] => 4 [4] => 2 ) 
Array ( [0] => 5 [1] => 4 [2] => 1 [3] => 2 ) 
Array ( [0] => 10 [1] => 5 [2] => 1 [3] => 4 ) 
Array ( [0] => 10 [1] => 9 [2] => 5 [3] => 4 [4] => 1 )

posted on 2012-09-16 00:18  ZimZz  阅读(1690)  评论(0编辑  收藏  举报