二叉树的基本概念
1、二叉树:在二叉树中,每个节点最多有两个节点,一般被称为左子节点和右子节点,并且二叉树的子数有左右之分,其次序不能任意颠倒
以下是在Swift中实现通用二叉树的方法:
public indirect enum BinaryTree<T> {
case node(BinaryTree<T>, T, BinaryTree<T>)
case empty
}
例如,这是一个二叉树,表示一系列算术运算,(5 * (a - 10)) + (-4 * (3 / b)):
// 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)
添加description属性以便打印树:
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 ""
}
}
}
另一个有用的属性是计算树中的节点数:
public var count: Int {
switch self {
case let .node(left, _, right):
return left.count + 1 + right.count
case .empty:
return 0
}
}
遍历
遍历二叉树有三种方法:
前序遍历: 根结点-->左子树-->右子树。
中序遍历: 左子树-->根结点-->右子树。
后序遍历: 左子树-->右子树-->根结点。
这三种遍历方式分别称为:前序(Pre-order),中序(In-order),后序(Post-order)
以下是 Swift 实现的方法:
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 traverseInOrder(process: (T) -> Void) {
if case let .node(left, value, right) = self {
left.traverseInOrder(process: process)
process(value)
right.traverseInOrder(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)
}
}
题目一:求后序遍历
题目: 已知前序遍历 ABDGHCEIF 及中序遍历 GDHBAEICF,求出后序遍历顺序?
解答:
- 先序遍历的结果是ABDGHCEIF,根据先序得到根节点是A;中序遍历的结果是GDHBAEICF,根据中序得到A之前的节点都是左子树,A之后的节点都是右子树。
- 再对左右子树进行第一步的分析。最终能得到二叉树的完整结构。
题目二:求前序遍历
题目: 已知后序遍历 GHDBIEFCA 及中序遍历 GDHBAEICF,求出后序遍历顺序?
解答:
- 后序遍历的结果是GHDBIEFCA,根据先序得到根节点是A;中序遍历的结果是GDHBAEICF,根据中序得到A之前的节点都是左子树,A之后的节点都是右子树。
- 再对左右子树进行第一步的分析。最终能得到二叉树的完整结构。