今天项目,由于性能问题,需要修改排序算法。
根据项目实际情况,数据采用了分页结构,每页30条数据,对于第一页的数据,我只需要排出top30,第二页排出top60,所以不需要进行全部排序。
这样会导致一个问题,越靠后面的页数,性能越差,但在实际应用中,这里是要进行的是排序(排行),排行榜后面的数据也无意义,所以限制的最大排序量为top4000,足够了。
本人脑子很笨,没学过数据结构,自今没能理解堆排序的原理,同事讲了一下午也没听明白。
还好看CLUCENE的时候,知道lucene里实现了一个,索性照葫芦画瓢,将C++的实现修改为了PHP的实现,中途因一个变量名的原因,调试了一下午,在这里贴出来一下。
//使用方法如下,lessThan是比较函数,根据需要在子类中重写:
根据项目实际情况,数据采用了分页结构,每页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;
}
}
{
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";
}
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/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!
评论列表