麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

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

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開發資料庫,
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 91麻豆精品国产91久久久无需广告 | 黄色特级片黄色特级片 | 欧美另类在线视频 | 中国hd高清xxxxvideo | 欧美一级理论 | 亚洲成人福利 | 黄色片观看 | 1024亚洲天堂 | av免费在线播放 | 国产91精品一区二区麻豆亚洲 | 日本中文一级片 | 蜜桃视频在线免费播放 | 国产 视频 一区二区 | 在线成人免费观看 | 国产18视频 | 色播av在线 | 成人午夜免费在线视频 | 国产一区二区三区在线观看视频 | 91九色电影 | 看免费一级毛片 | 中文在线观看www | 黄色美女网站免费看 | 9797色| 999久久久久久 | 亚洲生活片 | 国产高潮好爽好大受不了了 | 羞羞视频一区 | 成人免费网站在线观看视频 | 色播视频在线播放 | 亚洲精品日韩色噜噜久久五月 | 国产精品久久久久久久成人午夜 | 免费毛片播放 | 九九黄色 | 蜜桃网在线 | 国产免费成人在线 | 久久久久性 | 99欧美精品 | 久久亚洲精品久久国产一区二区 | 久久久久久三区 | 久久久久免费精品国产小说色大师 | 欧美日韩亚洲在线观看 |