andyRon/swift-algorithm-club-cn

Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
 .. Failed to load latest commit information. BinaryTree.playground Images README.markdown README_en.markdown

二叉树（Binary Tree）

代码

```public indirect enum BinaryTree<T> {
case node(BinaryTree<T>, T, BinaryTree<T>)
case empty
}```

```// leaf nodes
let node5 = BinaryTree.node(.empty, "5", .empty)
let nodeA = BinaryTree.node(.empty, "a", .empty)
let node10 = BinaryTree.node(.empty, "10", .empty)
let node4 = BinaryTree.node(.empty, "4", .empty)
let node3 = BinaryTree.node(.empty, "3", .empty)
let nodeB = BinaryTree.node(.empty, "b", .empty)

// intermediate nodes on the left
let Aminus10 = BinaryTree.node(nodeA, "-", node10)
let timesLeft = BinaryTree.node(node5, "*", Aminus10)

// intermediate nodes on the right
let minus4 = BinaryTree.node(.empty, "-", node4)
let divide3andB = BinaryTree.node(node3, "/", nodeB)
let timesRight = BinaryTree.node(minus4, "*", divide3andB)

// root node
let tree = BinaryTree.node(timesLeft, "+", timesRight)```

```extension BinaryTree: CustomStringConvertible {
public var description: String {
switch self {
case let .node(left, value, right):
return "value: \(value), left = [\(left.description)], right = [\(right.description)]"
case .empty:
return ""
}
}
}```

``````value: +, left = [value: *, left = [value: 5, left = [], right = []], right = [value: -, left = [value: a, left = [], right = []], right = [value: 10, left = [], right = []]]], right = [value: *, left = [value: -, left = [], right = [value: 4, left = [], right = []]], right = [value: /, left = [value: 3, left = [], right = []], right = [value: b, left = [], right = []]]]
``````

``````value: +,
left = [value: *,
left = [value: 5, left = [], right = []],
right = [value: -,
left = [value: a, left = [], right = []],
right = [value: 10, left = [], right = []]]],
right = [value: *,
left = [value: -,
left = [],
right = [value: 4, left = [], right = []]],
right = [value: /,
left = [value: 3, left = [], right = []],
right = [value: b, left = [], right = []]]]
``````

```  public var count: Int {
switch self {
case let .node(left, _, right):
return left.count + 1 + right.count
case .empty:
return 0
}
}```

1. In-order（或深度优先）： 首先查看节点的左子节点，然后查看节点本身，最后查看其右子节点。
2. Pre-order： 首先查看节点，然后查看其左右子节点。
3. Post-order： 首先查看左右子节点最后处理节点本身。

```  public func traverseInOrder(process: (T) -> Void) {
if case let .node(left, value, right) = self {
left.traverseInOrder(process: process)
process(value)
right.traverseInOrder(process: process)
}
}

public func traversePreOrder(process: (T) -> Void) {
if case let .node(left, value, right) = self {
process(value)
left.traversePreOrder(process: process)
right.traversePreOrder(process: process)
}
}

public func traversePostOrder(process: (T) -> Void) {
if case let .node(left, value, right) = self {
left.traversePostOrder(process: process)
right.traversePostOrder(process: process)
process(value)
}
}```

``````5
a
10
-
*
4
-
3
b
/
*
+
``````

```tree.traversePostOrder { s in
switch s {
case this is a numeric literal, such as 5:
push it onto the stack
case this is a variable name, such as a:
look up the value of a and push it onto the stack
case this is an operator, such as *:
pop the two top-most items off the stack, multiply them,
and push the result back onto the stack
}
the result is in the top-most item on the stack
}```