2017-10-14 105 views
1

下面的代碼應該通過遍歷從紅色黑樹的根節點到底部的左節點來計算黑節點。黑節點的數量存儲在變量black將程序樣式方法轉換爲函數樣式

fun isBalanced1(): Boolean { 
    require(!isEmpty()) { "Cannot check empty tree for balance"} 
    var x = root 
    var black = 0 
    while(x != null) { 
     if(!isRed(x)) { 
      black++ 
     } 
     x = x.left 
    } 
    return isBalanced(root, black) 
} 

風格是程序性和它的作品確定。

現在怎麼能改變在一個更實用的風格做同樣的事情?

這是我想出了:

fun isBalanced1(): Boolean { 
    require(!isEmpty()) { "Cannot check empty tree for balance" } 
    val black = 
      generateSequence(root) { node -> node.left } 
        .takeWhile { node -> node != null } 
        .filter { node -> !isRed(node) }.count() 
    return isBalanced(root, black) 
} 

它使用一個序列發生器遍歷樹而節點不是null,然後過濾黑色的和計數的所有比賽。

這是轉換此樹遍歷代碼的正確方法還是Kotlin中有更好的替代方法?

+1

我在這段代碼中看不到任何遞歸?順便說一句,我會把'.count()'放在換行符後面 – Bergi

+0

@Bergi:你說的是遞歸。沒有遞歸調用。我編輯了這個問題並刪除了它,因爲它很混亂。 –

+2

'takeWhile'不是必需的,因爲'generateSequence'在遇到的第一個null時停止。 'filter {} .count()'相當於'count {}' – Ilya

回答

0

繼在評論中給出的建議,這是代碼應如何看起來像:

fun isBalanced(): Boolean { 
    require(!isEmpty()) { "Cannot check empty tree for balance" } 
    val blackCount = 
      generateSequence(root) { node -> node.left } 
        .count { !isRed(it) } 
    return isBalanced(root, blackCount) 
} 

方法count()是在自己的段可讀性和takeWhile是沒有必要的。

+0

你可以合併過濾器和計數@Ilya說:'generateSequence(root){it.left} .count {!isRed(it)}' –