二叉树是一种特殊的Tree,每个节点最多只能包含2个子节点。

实现一个BinaryNode
public class BinaryNode<Element> {
public var value: Element
public var leftChild: BinaryNode?
public var rightChild: BinaryNode?
public init(value: Element) {
self.value = value
}
}
跟之前的TreeNode唯一区别就是子节点。
var tree: BinaryNode<Int> = {
let zero = BinaryNode(value: 0)
let one = BinaryNode(value: 1)
let five = BinaryNode(value: 5)
let seven = BinaryNode(value: 7)
let eight = BinaryNode(value: 8)
let nine = BinaryNode(value: 9)
seven.leftChild = one
one.leftChild = zero
one.rightChild = five
seven.rightChild = nine
nine.leftChild = eight
return seven
}()
一个很简单的二叉树,用图形表示如下

之前 Tree 的遍历,我们写了两种方式Depth-first 和 level-order 同样适用于二叉树。二叉树是特殊的Tree,它也有他自己的特殊的遍历方式。in-order、pre-order 、post-order 。
In-order 遍历
递归的 left child -> self -> right child

如这个图的顺序就是 0 1 5 7 8 9
// in order
extension BinaryNode {
public func traverseInOrder(visit: (Element) -> Void) {
leftChild?.traverseInOrder(visit: visit)
visit(value)
rightChild?.traverseInOrder(visit: visit)
}
}
tree.traverseInOrder { print($0) }
// result:
0
1
5
7
8
9
pre-order 遍历
递归的 self -> left child -> right child

// pre-order
extension BinaryNode {
public func traversePreOrder(visit: (Element) -> Void) {
visit(value)
leftChild?.traversePreOrder(visit: visit)
rightChild?.traversePreOrder(visit: visit)
}
}
tree.traversePreOrder { print($0) }
// result:
7
1
0
5
9
8
post-order 遍历
递归的 left child -> right child -> self

这个图的顺序就是 0 5 1 8 9 7
// post-order
extension BinaryNode {
public func traversePostOrder(visit: (Element) -> Void) {
leftChild?.traversePostOrder(visit: visit)
rightChild?.traversePostOrder(visit: visit)
visit(value)
}
}
tree.traversePostOrder { print($0) }
// result:
0
5
1
8
9
7
这些遍历算法的时间复杂度都是O(n)
求二叉树的高度
extension BinaryNode {
private func binaryTreeHeight(node: BinaryNode<Element>?) -> Int{
var height = 0
if let node = node {
let leftHeight = binaryTreeHeight(node: node.leftChild)
let rightHeight = binaryTreeHeight(node: node.rightChild)
height = leftHeight >= rightHeight ? (leftHeight + 1):(rightHeight + 1)
}
return height
}
public func getHeight() -> Int{
return binaryTreeHeight(node: self)
}
}
let treeHeight = tree.getHeight()
print(treeHeight)
// result: 3
将二叉树序列化成数组
extension BinaryNode {
private func serializeItem(_ node: BinaryNode<Element>?) -> [Element?]{
var array: [Element?] = []
if let node = node {
array.append(node.value)
let leftItems = serializeItem(node.leftChild)
leftItems.forEach({ array.append($0) })
let rightItems = serializeItem(node.rightChild)
rightItems.forEach({ array.append($0) })
}else{
array.append(nil)
}
return array
}
public func serializeToArray() -> [Element?]{
return serializeItem(self)
}
}
let array = tree.serializeToArray()
print(array)
// result:
[Optional(7), Optional(1), Optional(0), nil, nil, Optional(5), nil, nil, Optional(9), Optional(8), nil, nil, nil]
还是适用递归的思想
将上面的数组反序列化为二叉树
先写一个description方法 ,让二叉树打印出来好看一些
extension BinaryNode {
public var description: String {
return diagram(for: self)
}
private func diagram(for node: BinaryNode?,
_ top: String = "",
_ root: String = "",
_ bottom: String = "") -> String {
guard let node = node else {
return root + "nil\n"
}
if node.leftChild == nil && node.rightChild == nil {
return root + "\(node.value)\n"
}
return diagram(for: node.rightChild,
top + " ", top + "┌──", top + "│ ")
+ root + "\(node.value)\n"
+ diagram(for: node.leftChild,
bottom + "│ ", bottom + "└──", bottom + " ")
}
}
然后写反序列化的算法,还是递归的思想。
// 将数组反序列化为二叉树
func deserialize(array:inout [Int?]) -> BinaryNode<Int>?{
guard !array.isEmpty, let value = array.removeFirst() else {
return nil
}
let node = BinaryNode(value: value)
node.leftChild = deserialize(array: &array)
node.rightChild = deserialize(array: &array)
return node
}
var array = tree.serializeToArray()
let node = deserialize(array: &array)
print(node?.description ?? "")
// result:
┌──nil
┌──9
│ └──8
7
│ ┌──5
└──1
└──0
内容来自《Data Structure & Algorithms in Swift》简记