a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 學院 > 邏輯算法 > 正文

php:樹形結構的算法 2

2024-09-08 23:18:45
字體:
來源:轉載
供稿:網友
  1 food 18
  |
  +---------------------------------------+
  | |
  2 fruit 11 12 meat 17
  | |
  +------------------------+ +---------------------+
  | | | |
  3 red 6 7 yellow 10 13 beef 14 15 pork 16
  | |
  4 cherry 5 8 banana 9
  
  這樣整個樹狀結構可以通過左右值來存儲到數據庫中。繼續之前,我們看一看下面整理過的數據表。
  
  
  +-----------------------+-----+-----+
  | parent | name | lft | rgt |
  +-----------------------+-----+-----+
  | | food | 1 | 18 |
  | food | fruit | 2 | 11 |
  | fruit | red | 3 | 6 |
  | red | cherry | 4 | 5 |
  | fruit | yellow | 7 | 10 |
  | yellow | banana | 8 | 9 |
  | food | meat | 12 | 17 |
  | meat | beef | 13 | 14 |
  | meat | pork | 15 | 16 |
  +-----------------------+-----+-----+
  注意:由于"left"和"right"在 sql中有特殊的意義,所以我們需要用"lft"和"rgt"來表示左右字段。 另外這種結構中不再需要"parent"字段來表示樹狀結構。也就是 說下面這樣的表結構就足夠了。
  
  +------------+-----+-----+
  | name | lft | rgt |
  +------------+-----+-----+
  | food | 1 | 18 |
  | fruit | 2 | 11 |
  | red | 3 | 6 |
  | cherry | 4 | 5 |
  | yellow | 7 | 10 |
  | banana | 8 | 9 |
  | meat | 12 | 17 |
  | beef | 13 | 14 |
  | pork | 15 | 16 |
  +------------+-----+-----+
  好了我們現在可以從數據庫中獲取數據了,例如我們需要得到"fruit"項下的所有所有節點就可以這樣寫查詢語句: select * from tree where lft between 2 and 11; 這個查詢得到了以下的結果。
  
  
  +------------+-----+-----+
  | name | lft | rgt |
  +------------+-----+-----+
  | fruit | 2 | 11 |
  | red | 3 | 6 |
  | cherry | 4 | 5 |
  | yellow | 7 | 10 |
  | banana | 8 | 9 |
  +------------+-----+-----+
  看到了吧,只要一個查詢就可以得到所有這些節點。為了能夠像上面的遞歸函數那樣顯示整個樹狀結構,我們還需要對這樣的查詢進行排序。用節點的左值進行排序:
  
  select * from tree where lft between 2 and 11 order by lft asc;
  剩下的問題如何顯示層級的縮進了。
  
  <?php
  function display_tree($root)
  {
  // 得到根節點的左右值
  $result = mysql_query('select lft, rgt from tree '.'where name="'.$root.'";');
  $row = mysql_fetch_array($result);
  
  // 準備一個空的右值堆棧
  $right = array();
  
  // 獲得根基點的所有子孫節點
  $result = mysql_query('select name, lft, rgt from tree '.
  'where lft between '.$row['lft'].' and '.
  $row['rgt'].' order by lft asc;');
  
  // 顯示每一行
  while ($row = mysql_fetch_array($result))
  {
  // only check stack if there is one
  if (count($right)>0)
  {
  // 檢查我們是否應該將節點移出堆棧
  while ($right[count($right)-1]<$row['rgt'])
  {
  array_pop($right);
  }
  }
  
  // 縮進顯示節點的名稱
  echo str_repeat(' ',count($right)).$row['name']."n";
  
  // 將這個節點加入到堆棧中
  $right[] = $row['rgt'];
  }
  }
  ?>
  如果你運行一下以上的函數就會得到和遞歸函數一樣的結果。只是我們的這個新的函數可能會更快一些,因為只有2次數據庫查詢。 要獲知一個節點的路徑就更簡單了,如果我們想知道cherry 的路徑就利用它的左右值4和5來做一個查詢。
  
  select name from tree where lft < 4 and rgt > 5 order by lft asc;
  這樣就會得到以下的結果:
  
  +------------+
  | name |
  +------------+
  | food |
  | fruit |
  | red |
  +------------+
  那么某個節點到底有多少子孫節點呢?很簡單,子孫總數=(右值-左值-1)/2 descendants = (right – left - 1) / 2 不相信?自己算一算啦。用這個簡單的公式,我們可以很快的算出"fruit 2-11"節點有4個子孫節點,而"banana 8-9"節點沒有子孫節點,也就是說它不是一個父節點了。
  很神奇吧?雖然我已經多次用過這個方法,但是每次這樣做的時候還是感到很神奇。
  
  這的確是個很好的辦法,但是有什么辦法能夠幫我們建立這樣有左右值的數據表呢?這里再介紹一個函數給大家,這個函數可以將name和parent結構的表自動轉換成帶有左右值的數據表。
  
  
  <?php
  function rebuild_tree($parent, $left) {
  // the right value of this node is the left value + 1
  $right = $left+1;
  
  // get all children of this node
  $result = mysql_query('select name from tree '.
  'where parent="'.$parent.'";');
  while ($row = mysql_fetch_array($result)) {
  // recursive execution of this function for each
  // child of this node
  // $right is the current right value, which is
  // incremented by the rebuild_tree function
  $right = rebuild_tree($row['name'], $right);
  }
  
  // we've got the left value, and now that we've processed
  // the children of this node we also know the right value
  mysql_query('update tree set lft='.$left.', rgt='.
  $right.' where name="'.$parent.'";');
  
  // return the right value of this node + 1
  return $right+1;
  }
  ?>
  當然這個函數是一個遞歸函數,我們需要從根節點開始運行這個函數來重建一個帶有左右值的樹
  
  rebuild_tree('food',1);
  這個函數看上去有些復雜,但是它的作用和手工對表進行編號一樣,就是將立體多層結構的轉換成一個帶有左右值的數據表。

注冊會員,創建你的web開發資料庫,
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 成人在线 | 色婷婷在线播放 | 毛片免费观看网址 | 欧美激情精品久久久久 | 一区亚洲| 鲁视频| 在线免费自拍 | 国产涩涩| 欧美三级 欧美一级 | 欧美亚洲国产日韩 | 国产精品视频一区二区三区不卡 | 欧美a在线 | 高清视频一区二区三区 | 99国内精品久久久久久久 | 仙人掌旅馆在线观看 | 成人欧美一区二区三区1314 | 99爱在线观看 | 欧美成视频 | 成人精品在线视频 | 亚洲人人爽 | 亚洲一级性 | 久久久久中文字幕 | 日韩成人影视 | 2020天天操 | 天堂一区二区三区 | 亚洲专区在线播放 | 色综合天天综合网天天看片 | 国产一区二区三区久久久 | 97在线免费 | 男人的天堂久久 | 三级精品| 亚洲国产精品久久 | 国产极品美女高潮抽搐免费网站 | 国产一区二区三区四区视频 | 日韩一区二区三区四区五区六区 | 亚洲日韩视频免费观看 | 人妖 丝袜 另类 亚洲 | 日韩欧美在线一区 | 国产精品18hdxxxⅹ在线 | 五月婷婷在线视频观看 | 亚洲精品久久 |