2017-07-24 23 views
0

我需要從左側或右側子樹中的所有二叉樹中獲得某個級別的所有節點。我目前檢索數據庫二叉樹作爲數組,例如: [1,2,3,4,5,6,7]表示像這樣的樹:以完全二叉樹的形式獲取所有節點,陣列格式

         1 
            /\ 
           / \ 
            2  3 
           /\ /\ 
           / \/ \ 
           4 5 6 7 

所以我需要做的基本上是搶樹的級別並回到它作爲一個陣列。類似level(3,"left") -> [4,5]level(2, "right") -> [3]。我正在考慮以遞歸方式創建一個BinaryTree對象,但我無法想出一種方法來跟蹤調用中的級別,而無需使用級別標記每個節點或類似的東西,因爲我想保留數據庫儘可能乾淨。有任何想法嗎?

編輯:我真的需要左或右子樹中的所有節點,而不是整棵樹。我正在展示一個比賽,所以我需要將它分成一半和一半。如果我沒有分裂的話,我也許可以這樣做:

function level($array, $level_num) { 
    return array_slice($array, pow(2, $level_num)-1, pow(2, $level_num)); 
} 

我真的不知道如何擴展這樣來僅左或右子樹的水平陣列。

+0

這是一個非常酷的問題。試試看,並顯示您的失敗代碼。另請注意,您呈現的圖像與示例數組不匹配。該數組有4和沒有8.該圖像沒有4,但有一個8. – BeetleJuice

+0

@BeetleJuice對不起,沒有注意到。只是更新了它。 – ashraj98

+0

好吧,我寫了一個解決方案。在你的OP中,'level(3)'仍然包含'8',即使它不在樹中。 – BeetleJuice

回答

0

我upvoted陰間大法師的回答使用「左移」位運算符<< - 這是這個任務的最佳基石。

這是乾淨的,我可以讓我的編碼嘗試:

代碼:(Demo

function getForkinValues($array,$level,$side='left'){ // left side fork is default 
    if($level==1) return current($array); 
    $length=$level>2?1<<($level-2):1; // number of elements to return 
    $index=(1<<$level-1)-1;   // first index to return 
    if($side=='right') $index+=$length; // shift to correct index for 'right' 
    if(!isset($array[$index+$length-1])) return 'Error: Insufficient Array Length'; 
    return array_slice($array,$index,$length); 

} 
$array=['A','B','C','D','E','F','G']; 
var_export(getForkinValues($array,3,'right')); 
+0

@ ashraj98我沒有引用任何索引。這個功能(比如BeetleJuice's)不會打擾「增長整棵樹」。它確定樹中指定「級別」的整數,並在指定分叉中返回一組值。構建一棵完整的樹(多暗淡陣列)只能提取一小部分 - 效率低下/浪費。最佳做法是隻建立你所需要的。 – mickmackusa

+0

是的,我意識到,看了一下之後。假設樹節點不是'[1,2,3,4,5,...]'?我只用OP中的樹作爲例子。在實際使用中,節點值是Laravel中模型的ID,所以它不會像這個例子那樣。 – ashraj98

2
// Adjust depth as needed 
$depth = 3; 

// using bit arithmetic. '<< 3' means multiply by 2 three times. 
$start = 1 << $depth-1; // 1 * (2 * 2) because depth is 3 
$end = (1 << $depth) -1; // 1 * (2 * 2 * 2) - 1 

// if depth=3, this is [4,5,6,7] 
$fullLevel = range($start, $end); 

print_r($fullLevel); 

if($depth > 1): 
    $leftBranch = array_slice($fullLevel,0,count($fullLevel)/2); 
    $rightBranch = array_slice($fullLevel,count($fullLevel)/2); 

    print_r($leftBranch); // [4,5] 
    print_r($rightBranch); // [6, 7] 
endif; 
+0

我意識到獲得左邊或右邊的部分只是把它分成兩半。使用'<<而不是'pow()'有什麼好處,還是我有一些不同之處? – ashraj98

+0

@ ashraj98'pow()'將遠離你...這是[demo](http://sandbox.onlinephpfunctions.com/code/2dd1aea11831b11e9033d5174091d25407a996ce)。 – mickmackusa