求教大家一個小演算法問題

來源:互聯網
上載者:User
樹狀流程圖:


表結構


這個表結構就是每個節點都有三個子節點,left、center、right,要求就是在適當的位置插入節點,插入的規則就是:假設從id=1開始,然後找出其下的三個子節點,如果三個子節點都存在,就分別尋找三個子節點的子節點。直到所在的子節點沒有資料,就可以插入了


具體流程走法:如樹狀圖:id = 1開始尋找,尋找其子節點,有2 ,3, 4,都是存在的,然後在尋找2的子節點,5,6,7也都是存在的,然後在尋找3的子節點,只有8,然後就可以在3的中間的子節點插入了。當然資料越多,尋找的也會越多。一直在想,沒想出來,急的很,希望大神給個具體代碼的演算法,萬分感謝。


回複討論(解決方案)

這麼有規律的東西,不用考慮那麼複雜吧
從1開始,每個數字3個子節點,可以推匯出公式計算任何位置所處層數和上下層的數字
資料表正常記錄就好

我上面說的數字只是舉例,有可能id=1下面是111,121,220,靠公式推導這個會出問題恩

#1說的沒錯,你自左向右依次填寫就可以了,填滿就加一條記錄

話說你雖然畫了個樹,實際上並沒用枝葉間的關係

三叉?,可以?考二叉?的演算法。

select id from table where left_id is null order by id limit 1;//如果存在 則可以往這個id 插入 左節點,然後結束return;select id from table where center_id is null order by id limit 1;//如果存在 則可以往這個id 插入 中間節點,然後結束return;select id from table where right_id is null order by id limit 1;//如果存在 則可以往這個id 插入 右節點,然後結束return;//直接插入id

可以先查最大id,然後查它的所有left、center、right
(1)如果都有,說明已滿,直接插入新紀錄的left
(2)如果left、center有,插入right
(3)如果left有,插入center
目前你這個流程圖(遞增欄位)最大的問題是,如果有刪除需求,怎麼調整id

以前在網上找到的php二叉樹,我改了一點,變成三叉樹,其實就加了個center

class Node {public $data = null;public $parent = null;public $left = null;public $center =null;public $right = null;}function build_cbtree($a) {$root = new Node();$root->data = $a[0];for ($i = 1; $i < count($a); $i++) {$node = new Node();$node->data = $a[$i];insert_node($root, $node);}return $root;}function insert_node($root, $inode) {$queue = array();array_unshift($queue, $root);while (!empty($queue)) {$cnode = array_pop($queue);if ($cnode->left == null) {$cnode->left = $inode;$inode->parent = $cnode;return $root;} else {array_unshift($queue, $cnode->left);                }if ($cnode->center == null) {$cnode->center = $inode;$inode->parent = $cnode;return $root;} else {array_unshift($queue, $cnode->center);}if ($cnode->right == null) {$cnode->right = $inode;$inode->parent = $cnode;return $root;} else {array_unshift($queue, $cnode->right);}}return $root;}//廣度優先遍曆(先遍曆一層,再遍曆下一層)function bf_traverse($root) {$queue = array();array_unshift($queue, $root);while (!empty($queue)) {$cnode = array_pop($queue);echo $cnode->data . " ";if ($cnode->left !== null) array_unshift($queue, $cnode->left);if ($cnode->center !== null) array_unshift($queue, $cnode->center);if ($cnode->right !== null) array_unshift($queue, $cnode->right);}}$a = array(1,2,3,4,5,6,7,8);//先把數組變成三叉樹$root = build_cbtree($a);echo "
";print_r($root);echo "
";bf_traverse($root);/*$root資料太多就不打出來了根據廣度優先遍曆規則得1 2 3 4 5 6 7 8*///此時$root就是一個三叉樹//插入9,其實就是重複build_cbtree的方法中for迴圈的代碼$node1 = new Node();$node1->data =9;insert_node($root, $node1);echo "
";print_r($root);echo "
";bf_traverse($root);/*Node Object( [data] => 1 [parent] => [left] => Node Object ( [data] => 2 [parent] => Node Object *RECURSION* [left] => Node Object ( [data] => 5 [parent] => Node Object *RECURSION* [left] => [center] => [right] => ) [center] => Node Object ( [data] => 6 [parent] => Node Object *RECURSION* [left] => [center] => [right] => ) [right] => Node Object ( [data] => 7 [parent] => Node Object *RECURSION* [left] => [center] => [right] => ) ) [center] => Node Object ( [data] => 3 [parent] => Node Object *RECURSION* [left] => Node Object ( [data] => 8 [parent] => Node Object *RECURSION* [left] => [center] => [right] => ) [center] => Node Object ( [data] => 9 [parent] => Node Object *RECURSION* [left] => [center] => [right] => ) [right] => ) [right] => Node Object ( [data] => 4 [parent] => Node Object *RECURSION* [left] => [center] => [right] => ))根據廣度優先遍曆規則得1 2 3 4 5 6 7 8 9*/


[center] => Node Object
(
[data] => 9
[parent] => Node Object
*RECURSION*
[left] =>
[center] =>
[right] =>
)
就是插入進去的位置

可以先查最大id,然後查它的所有left、center、right
(1)如果都有,說明已滿,直接插入新紀錄的left
(2)如果left、center有,插入right
(3)如果left有,插入center
目前你這個流程圖(遞增欄位)最大的問題是,如果有刪除需求,怎麼調整id

這個沒有刪除需求,只有增加

雖然不明白這個有什麼實際用途,但是實現起來也還是不算難的

mysql_connect();mysql_selectdb('test');mysql_query("create temporary table T (id int, left_id int null, conter_id int null, right_id int null)");for($i=1; $i<=8; $i++) {  $rs = mysql_query("select * from T where right_id is null limit 1");  if(mysql_num_rows($rs) == 0) {    mysql_query("insert into T (id) values ($i)");    continue;  }  foreach($r = mysql_fetch_assoc($rs) as $k=>$v) {    if($k == 'id') continue;    if(empty($v)) {      mysql_query("insert into T (id) values ($i)");      mysql_query("update T set $k=$i where id=$r[id]");      break;    }  }}$rs = mysql_query('select * from T');while($r = mysql_fetch_row($rs)) {  echo join("\t", $r), PHP_EOL;}
123425673845678
  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.