Es ist der Spielplatz, der mit Ihrem Kopf spielt.
Playground zählt eigene Aufrufe für Variablen, die über das CustomStringContibe-Protokoll verfügen (wahrscheinlich, um die Informationen auf der rechten Seite einzufügen).
Sie können dies sehen, wenn Sie einfach Spiegel (Baum) aufrufen, ohne überhaupt zu drucken.
Wenn Sie die tatsächliche Anzahl von Anrufungen mit Ihrem eigenen Zähler zählen, wird es ein ganz anderes Ergebnis geben:
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
By the way, ich hatte ein wenig Schwierigkeiten zu verstehen, den Spiegel() Funktion und ich dachte, ein rekursiver wäre wahrscheinlich einfacher zu verstehen. Wie wäre es einen Spiegel() Funktion zu Knoten hinzufügen:
func mirror() -> Node
{
let result = Node()
result.id = id
result.left = right?.mirror()
result.right = left?.mirror()
return result
}
print(tree.mirror())
[EDIT] Hier ist eine nicht-rekursive Spiegelfunktion (gleiche Logik wie bei Ihnen) mit einer etwas klareren Struktur:
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
}
und einige visuelle Süßigkeiten für Baum Beschreibungen:
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!)" : "")
}
}
in einem einfacheren Vergleich der Ergebnisse resultierende:
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
Dank @Alain T .. Über die Mirror-Funktion, die Gist ist über die Implementierung es ohne Rekursion, deshalb ist: D –