php的PriorityQueue(优先级队列的实现)

jackxiang 2009-11-16 13:04 | |
今天项目,由于性能问题,需要修改排序算法。

根据项目实际情况,数据采用了分页结构,每页30条数据,对于第一页的数据,我只需要排出top30,第二页排出top60,所以不需要进行全部排序。

这样会导致一个问题,越靠后面的页数,性能越差,但在实际应用中,这里是要进行的是排序(排行),排行榜后面的数据也无意义,所以限制的最大排序量为top4000,足够了。



本人脑子很笨,没学过数据结构,自今没能理解堆排序的原理,同事讲了一下午也没听明白。

还好看CLUCENE的时候,知道lucene里实现了一个,索性照葫芦画瓢,将C++的实现修改为了PHP的实现,中途因一个变量名的原因,调试了一下午,在这里贴出来一下。


class PriorityQueue
{
private $heap;
private $_size;
private $maxSize;

public function debug()
{
  print_r($this->heap);
}
private function upHeap()
{
  
  $i=$this->_size;
  $node=$this->heap[$i];
  $j=intval($i>>1);
  while($j>0&&$this->lessThan($node,$this->heap[$j]))
  {
   $this->heap[$i]=$this->heap[$j];
   $i=$j;
   $j=intval($j>>1);
  }
  $this->heap[$i]=$node;
  
}

private function downHeap()
{
  $i=1;
  $node=$this->heap[$i];
  $j=intval($i<<1);
  $k=$j+1;
  if($k<=$this->_size&&$this->lessThan($this->heap[$k],$this->heap[$j]))
  {
   $j=$k;
  }
  
  while($j<=$this->_size&&$this->lessThan($this->heap[$j],$node))
  {
   $this->heap[$i]=$this->heap[$j];
   $i=$j;
   $j=intval($i<<1);
   $k=$j+1;
   if($k<=$this->_size&&$this->lessThan($this->heap[$k],$this->heap[$j]))
   {
    $j=$k;
   }
  }
  $this->heap[$i]=$node;
}


function __construct()
    {
  $this->_size=0;
  $this->heap=null;
  $this->maxSize=0;
    }
    
    function __destruct()
{
  $this->clear();
  unset($this->heap);
}

function put($element)
{
  if($this->_size>=$this->maxSize)
  {
   return false;
  }
  ++$this->_size;
  $this->heap[$this->_size]=$element;
  $this->upHeap();
  return true;
}

function insert($element)
{
  if($this->_size<$this->maxSize)
  {
   return $this->put($element);
  }
  else if($this->_size>0)
  {
   $top=$this->top();
   if(!$this->lessThan($element,$top))
   {
    $this->heap[1]=$element;
    $this->adjustTop();
    return true;
   }
  
  }
  return false;
}


function top()
{
  if($this->_size>0)
  {
   return $this->heap[1];
  }
  
  return null;
}

function pop()
{
  if($this->_size>0)
  {
   $result=$this->heap[1];
   $this->heap[1]=$this->heap[$this->_size];
   $this->heap[$this->_size]=0;
   --$this->_size;
   $this->downHeap();
   return $result;
  }
  return null;
}


function adjustTop()
{
  $this->downHeap();
}


function size()
{
  return $this->_size;
}

function clear()
{
  $this->_size=0;
}
    
    public function initialize($maxSize)
    {
     $this->_size=0;
     $heapSize=$maxSize+1;
     $this->heap=array();
     for($i=0;$i<$heapSize;$i++)
     {
      $this->heap[]=0;
     }
     $this->maxSize=$maxSize;
    }



//根据需要在子类中重写
public function lessThan($cmp1,$cmp2)
{
  return $cmp1<$cmp2;
}
  
}





//使用方法如下,lessThan是比较函数,根据需要在子类中重写:


$arrayRand=array();
for($i=10;$i>=0;$i--)
{
$arrayRand[]=rand(0, 10);;
}

print_r($arrayRand);

$query=new PriorityQueue();
$query->initialize(5);
foreach($arrayRand as $eachValue)
{
$query->insert($eachValue);
}
while(true)
{
$element=$query->pop();
if($element===null)
{
  break;
}
echo "###{$element}\n";
}

作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:https://jackxiang.com/post/2226/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!

评论列表
发表评论

昵称

网址

电邮

打开HTML 打开UBB 打开表情 隐藏 记住我 [登入] [注册]