久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

PHP利用二叉堆實現TopK-算法的方法詳解

這篇文章主要給大家介紹了PHP利用二叉堆實現TopK-算法的方法,文中介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面跟著小編一起來學習學習吧。

前言

在以往工作或者面試的時候常會碰到一個問題,如何實現海量TopN,就是在一個非常大的結果集里面快速找到最大的前10或前100個數,同時要保證內存和速度的效率,我們可能第一個想法就是利用排序,然后截取前10或前100,而排序對于量不是特別大的時候沒有任何問題,但只要量特別大是根本不可能完成這個任務的,比如在一個數組或者文本文件里有幾億個數,這樣是根本無法全部讀入內存的,所以利用排序解決這個問題并不是最好的,所以我們這里就用php去實現一個小頂堆來解決這個問題.

二叉堆

二叉堆是一種特殊的堆,二叉堆是完全二叉樹或者是近似完全二叉樹,二叉堆有兩種,最大堆 和 最小堆,最大堆:父結點的鍵值總是大于或等于任何一個子節點的鍵值;最小堆:父結點的鍵值總是小于或等于任何一個子節點的鍵值

PHP利用二叉堆實現TopK-算法的方法詳解
小頂堆-(圖片來自網絡)

二叉堆一般用數組來表示(看上圖),例如,根節點在數組中的位置是0,第n個位置的子節點分別在2n+1和 2n+2,因此,第0個位置的子節點在1和2,1的子節點在3和4,以此類推,這種存儲方式便於尋找父節點和子節點。

具體概念問題這里就不在多說了,如果對二叉堆有疑問的可以在好好了解下這個數據結構,下面我們就針對上述topN問題來用php代碼實現并解決,為了看出區別這里先用排序的方式去實現下看下效果如何。

利用快速排序算法來實現 TopN

//為了測試運行內存調大一點
ini_set('memory_limit', '2024M');

//實現一個快速排序函數
function quick_sort(array $array){
 $length = count($array);
 $left_array = array();
 $right_array = array();
 if($length <= 1){
  return $array;
 }
 $key = $array[0];
 for($i=1;$i<$length;$i++){
  if($array[$i] > $key){
   $right_array[] = $array[$i];
  }else{
   $left_array[] = $array[$i];
  }
 }
 $left_array = quick_sort($left_array);
 $right_array = quick_sort($right_array);
 return array_merge($right_array,array($key),$left_array); 
}

//構造500w不重復數
for($i=0;$i<5000000;$i++){
 $numArr[] = $i; 
}
//打亂它們
shuffle($numArr);

//現在我們從里面找到top10最大的數
var_dump(time());
print_r(array_slice(quick_sort($all),0,10));
var_dump(time());

PHP利用二叉堆實現TopK-算法的方法詳解

運行之后結果

可以看到上面打印出了top10的結果,并輸出了下運行時間,大概99s左右,但這只是500w個數且全部能裝入內存的情況,如果我們有一個文件里面有5kw或5億個數,肯定就會有些問題了.

利用二叉堆算法來實現 TopN

實現流程是:

     1、先讀取10個或100個數到數組里面,這就是我們的topN數.

     2、調用生成小頂堆函數,把這個數組生成一個小頂堆結構,這個時候堆頂一定是最小的.

     3、從文件或者數組依次遍歷剩余的所有數.

     4、每遍歷出來一個則跟堆頂的元素進行大小比較,如果小于堆頂元素則拋棄,如果大于堆頂元素則替換之.

     5、跟堆頂元素替換完畢之后,在調用生成小頂堆函數繼續生成小頂堆,因為需要再找出來一個最小的.

     6、重復以上4~5步驟,這樣當全部遍歷完畢之后,我們這個小頂堆里面的就是最大的topN,因為我們的小頂堆永遠都是排除最小的留下最大的,而且這個調整小頂堆速度也很快,只是相對調整下,只要保證根節點小于左右節點就可以.

     7、算法復雜度的話按top10最壞的情況下,就是每遍歷一個數,如果跟堆頂進行替換,需要調整10次的情況,也要比排序速度快,而且也不是把所有的內容全部讀入內存,可以理解成就是一次線性遍歷.

//生成小頂堆函數
function Heap(&$arr,$idx){
 $left = ($idx << 1) + 1;
 $right = ($idx << 1) + 2;

 if (!$arr[$left]){
  return;
 }

 if($arr[$right] && $arr[$right] < $arr[$left]){
  $l = $right;
 }else{
  $l = $left;
 }

 if ($arr[$idx] > $arr[$l]){
   $tmp = $arr[$idx]; 
   $arr[$idx] = $arr[$l];
   $arr[$l] = $tmp;
   Heap($arr,$l);
 }
}

//這里為了保證跟上面一致,也構造500w不重復數
/*
 當然這個數據集并不一定全放在內存,也可以在
 文件里面,因為我們并不是全部加載到內存去進
 行排序
*/
for($i=0;$i<5000000;$i++){
 $numArr[] = $i; 
}
//打亂它們
shuffle($numArr);

//先取出10個到數組
$topArr = array_slice($numArr,0,10);

//獲取最后一個有子節點的索引位置
//因為在構造小頂堆的時候是從最后一個有左或右節點的位置
//開始從下往上不斷的進行移動構造(具體可看上面的圖去理解)
$idx = floor(count($topArr) / 2) - 1;

//生成小頂堆
for($i=$idx;$i>=0;$i--){
 Heap($topArr,$i);
}

var_dump(time());
//這里可以看到,就是開始遍歷剩下的所有元素
for($i = count($topArr); $i < count($numArr); $i++){
 //每遍歷一個則跟堆頂元素進行比較大小
 if ($numArr[$i] > $topArr[0]){
  //如果大于堆頂元素則替換
  $topArr[0] = $numArr[$i];
  /*
   重新調用生成小頂堆函數進行維護,只不過這次是從堆頂
   的索引位置開始自上往下進行維護,因為我們只是把堆頂
   的元素給替換掉了而其余的還是按照根節點小于左右節點
   的順序擺放這也就是我們上面說的,只是相對調整下,并
   不是全部調整一遍
  */
  Heap($topArr,0);
 }
}
var_dump(time());

PHP利用二叉堆實現TopK-算法的方法詳解

運行之后結果

【網站聲明】本站除付費源碼經過測試外,其他素材未做測試,不保證完整性,網站上部分源碼僅限學習交流,請勿用于商業用途。如損害你的權益請聯系客服QQ:2655101040 給予處理,謝謝支持。

相關文檔推薦

這篇文章主要介紹了PHP有序表查找之插值查找算法,簡單分析了插值查找算法的概念、原理并結合實例形式分析了php實現針對有序表插值查找的相關操作技巧,需要的朋友可以參考下
下面小編就為大家分享一篇ThinkPHP整合datatables實現服務端分頁的示例代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
下面小編就為大家分享一篇PHP實現APP微信支付的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
這篇文章主要介紹了PHP實現的多維數組排序算法,結合實例形式對比分析了php針對多維數組及帶有鍵名的多維數組進行排序相關操作技巧與注意事項,需要的朋友可以參考下
這篇文章主要為大家詳細介紹了php結合ajaxuploadfile實現無刷新文件上傳功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本篇文章給大家詳細介紹了PHP開發接口使用RSA進行加密解密方法,對此有興趣的朋友可以學習下。
主站蜘蛛池模板: 在线免费观看a级片 | 亚洲欧美日韩中文字幕一区二区三区 | 国产美女特级嫩嫩嫩bbb片 | 伊人久久在线 | 午夜男人的天堂 | www.国产精品 | 在线播放国产一区二区三区 | 国产高清视频在线观看播放 | 成人影院在线视频 | 久久中文字幕一区 | 91亚洲精品在线 | 免费精品 | 国产精品永久免费视频 | 日日夜夜影院 | 一区二区三区视频在线观看 | 久久久.com | 欧美日韩一区在线 | 伊人电影院av | 国产综合久久 | 97伦理影院 | 久久久久国产 | 不卡的av在线 | 精久久 | 日韩精品专区在线影院重磅 | 中国黄色在线视频 | 日韩免费视频 | 亚洲精品av在线 | 久久精品成人 | 亚洲精品日韩在线 | 国产精品福利视频 | 成人三区| 久久99精品久久久久久国产越南 | 青草视频在线 | 亚洲精品久久久蜜桃网站 | 免费毛片www com cn | 久久精品91久久久久久再现 | 亚洲狠狠丁香婷婷综合久久久 | 欧美成人精品二区三区99精品 | 中文字幕日韩欧美 | 天堂网中文| www性色|