Swift 数据结构 二叉树(Binary Tree)

673 阅读2分钟

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

binary

实现一个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
}()

一个很简单的二叉树,用图形表示如下

demo1

之前 Tree 的遍历,我们写了两种方式Depth-firstlevel-order 同样适用于二叉树。二叉树是特殊的Tree,它也有他自己的特殊的遍历方式。in-orderpre-orderpost-order

In-order 遍历

递归的 left child -> self -> right child

in-order

如这个图的顺序就是 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
如这个图的顺序就是 7 1 0 5 9 8

// 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

post-order

这个图的顺序就是 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》简记