# PriorityQueue.class.php

Go to the documentation of this file.

    00001 <?php
    00002 /***************************************************************************
    00003  *   Copyright (C) 2009 by Denis M. Gabaidulin                             *
    00004  *                                                                         *
    00005  *   This program is free software; you can redistribute it and/or modify  *
    00006  *   it under the terms of the GNU Lesser General Public License as        *
    00007  *   published by the Free Software Foundation; either version 3 of the    *
    00008  *   License, or (at your option) any later version.                       *
    00009  *                                                                         *
    00010  ***************************************************************************/
    00011
    00012     final class PriorityQueue
    00013     {
    00014         private $heap           = array(0);
    00015         private $heapSize       = 0;
    00016         private $cmpFunction    = null;
    00017
    00018         public function getLength()
    00019         {
    00020             return $this->heapSize;
    00021         }
    00022
    00023         public function first()
    00024         {
    00025             return $this->heap[1];
    00026         }
    00027
    00028         public static function create($unsortedData = array())
    00029         {
    00030             return new self($unsortedData);
    00031         }
    00032
    00033         public function __construct($unsortedData = array())
    00034         {
    00035             $this->heap = array_merge($this->heap, $unsortedData);
    00036
    00037             $this->heapSize = count($this->heap) - 1;
    00038
    00039             $this->buildMaxHeap();
    00040         }
    00041
    00042         /*
    00043         function cmp($one, $two)
    00044         {
    00045             if ($one['d'] == $two['d'])
    00046                 return 0;
    00047
    00048             return ($one['d'] < $two['d']) ? -1 : 1;
    00049         }
    00050         */
    00051         public function setCmpFunction($function)
    00052         {
    00053             $this->cmpFunction = $function;
    00054
    00055             return $this;
    00056         }
    00057
    00058         public function parent($index)
    00059         {
    00060             return $index >> 1;
    00061         }
    00062
    00063         public function left($index)
    00064         {
    00065             return $index << 1;
    00066         }
    00067
    00068         public function right($index)
    00069         {
    00070             return 1 + ($index << 1);
    00071         }
    00072
    00073         public function maxHeapify($index)
    00074         {
    00075             $left = $this->left($index);
    00076             $right = $this->right($index);
    00077
    00078             $largest = null;
    00079
    00080             $cmp = $this->cmpFunction;
    00081
    00082             if ($left <= $this->heapSize && $cmp($this->heap[$left], $this->heap[$index]) == 1)
    00083                 $largest = $left;
    00084             else
    00085                 $largest = $index;
    00086
    00087             if ($right <= $this->heapSize && $cmp($this->heap[$right], $this->heap[$largest]) == 1)
    00088                 $largest = $right;
    00089
    00090             if ($largest != $index) {
    00091                 $this->swapElts($index, $largest);
    00092
    00093                 $this->maxHeapify($largest);
    00094             }
    00095         }
    00096
    00097         public function buildMaxHeap()
    00098         {
    00099             for ($i = $this->heapSize / 2; $i > 0; $i--) {
    00100                 $this->maxHeapify($i);
    00101             }
    00102         }
    00103
    00104         public function pop()
    00105         {
    00106             if ($this->heapSize == 0)
    00107                 return null;
    00108
    00109             $max = $this->heap[1];
    00110
    00111             $this->heap[1] = $this->heap[$this->heapSize--];
    00112
    00113             $this->maxHeapify(1);
    00114
    00115             return $max;
    00116         }
    00117
    00118         public function push($elt)
    00119         {
    00120             ++$this->heapSize;
    00121
    00122             $this->heap[$this->heapSize] = PrimitiveInteger::SIGNED_MIN;
    00123
    00124             $index = $this->heapSize;
    00125
    00126             $this->heap[$index] = $elt;
    00127
    00128             $cmp = $this->cmpFunction;
    00129
    00130             while (
    00131                 $index > 1
    00132                 &&
    00133                     $cmp(
    00134                         $this->heap[$this->parent($index)],
    00135                         $this->heap[$index]
    00136                     ) == -1
    00137             ) {
    00138                 $this->swapElts($index, $this->parent($index));
    00139
    00140                 $index = $this->parent($index);
    00141             }
    00142         }
    00143
    00144         public function delete($index)
    00145         {
    00146             $this->heap[$index] = $this->heap[$this->heapSize];
    00147
    00148             unset($this->heap[$this->heapSize]);
    00149
    00150             $this->heapSize--;
    00151
    00152             $this->maxHeapify($index);
    00153         }
    00154
    00155         private function swapElts($index1, $index2)
    00156         {
    00157             $tmp                    = $this->heap[$index2];
    00158             $this->heap[$index2]    = $this->heap[$index1];
    00159             $this->heap[$index1]    = $tmp;
    00160         }
    00161     }
    00162 ?>