これはあなたの頭を乱している遊び場です。
Playgroundは、CustomStringConvertibeプロトコルを持つ変数に対して独自の呼び出しをカウントしています(おそらく右側のパネルに情報を入力する)。
ミラーリング(ツリー)を全く印刷せずに呼び出すだけでこれが実現します。
あなたがあなた自身のカウンタを使用して呼び出しの実際の数をカウントした場合、それは非常に異なった結果得られます:ところで
var descCount = 0
extension Node: CustomStringConvertible {
var description: String
{
descCount += 1
return "id: \(id)\nleft: \(left)\nright: \(right)"
}
}
descCount = 0
print(tree)
descCount // 12
descCount = 0
print(mirror(tree))
descCount // 12
を、私は鏡()関数を理解少し問題があったと私は考え出し再帰的なものはおそらく理解するのが簡単だろう。どのノードにミラー()関数の追加について:
func mirror() -> Node
{
let result = Node()
result.id = id
result.left = right?.mirror()
result.right = left?.mirror()
return result
}
print(tree.mirror())
[EDIT]ここでやや明確な構造を持つ非再帰ミラー機能(あなたと同じロジックが)です:
func mirror2(tree:Node) -> Node
{
// will return top of mirrored tree
let newTree = Node()
// node pair used for traversal and duplication
var original:Node! = tree
var mirrored:Node! = newTree
// traversal of tree structure left side first
// (uses mirrored tree to keep track of traversed nodes)
while original != nil
{
// carry node identifier (and contents eventually)
mirrored.id = original.id
// downwards, mirror left side first (if not already done)
if (original.left == nil) != (mirrored.right == nil)
{
original = original.left
mirrored.right = Node()
mirrored = mirrored.right
continue
}
// downwards, mirror right side second (if not already done)
if (original.right == nil) != (mirrored.left == nil)
{
original = original.right
mirrored.left = Node()
mirrored = mirrored.left
continue
}
// upwards from leaves and completed branches
original = original.parent
mirrored = mirrored.parent
}
return newTree
}
といくつかの視覚木の説明のためのお菓子:結果の比較を容易に結果
extension Node: CustomStringConvertible
{
var indent:String
{ return " " + (parent?.indent ?? "") }
var description: String
{
return "\(id)\n"
+ (left != nil ? "\(indent)L:\(left!)" : "")
+ (right != nil ? "\(indent)R:\(right!)" : "")
}
}
:
print(tree)
// 0
// L:1
// L:3
// L:7
// R:8
// R:4
// L:9
// R:10
// R:2
// R:6
// L:13
// R:14
//
print(mirror2(tree))
// 0
// L:2
// L:6
// L:14
// R:13
// R:1
// L:4
// L:10
// R:9
// R:3
// L:8
// R:7
ありがとう@Alain T ..ミラー関数について、要点は再帰を使用せずに実装することです –