《数据结构与算法》之链表
《数据结构与算法》之链栈
《数据结构与算法》之队列
《数据结构与算法》之排序
《数据结构与算法》之二分查找
作为一个程序员,你肯定听说过二叉树,树是一种非线性结构,比前面所讲的栈、队列这种线性结构复杂很多。我们先通过一张图来了解一下二叉树这种结构
我们把没有父节点的节点叫做根节点,也就是图中的节点 E。A 节点就是 B 节点的父节点,B 节点是 A 节点的子节点。B、C、D 这三个节点的父节点是同一个节点,所以它们之间互称为兄弟节点。我们把没有子节点的节点叫做叶子节点或者叶节点,比如图中的 G、H、I、J、K、L 都是叶子节点。
树有三个比较重要的概念:高度、深度、层,我们还是通过一张图来说明
二叉树的存储方式
二叉树的存储方式有两种,链式存储和顺序存储。
其中完全二叉树和满二叉树,合适使用顺序存储的方式
二叉树的操作
- 向二叉查找树添加一个节点
/// 向二叉查找树添加一个节点
/// - Parameters:
/// - binaryTree: 二叉查找树
/// - value: 值
/// - Returns: 二叉查找树
class func addTreeNode(binaryTree: inout BinaryTree?, value: Int) -> BinaryTree {
if binaryTree == nil {
//根节点不存在
binaryTree = BinaryTree.init()
binaryTree?.value = value
}else if value < binaryTree!.value! {
//值比节点的值小,插入左子树
binaryTree?.leftNode = self.addTreeNode(binaryTree: &binaryTree!.leftNode, value: value)
}else {
//值比节点的值大,插入右子树
binaryTree?.rightNode = self.addTreeNode(binaryTree: &binaryTree!.rightNode, value: value)
}
return binaryTree!
}
- 从二叉查找树中查找一个节点
/// 从二叉查找树中查找一个节点
/// - Parameters:
/// - binaryTree: 二叉查找树
/// - value: 值
/// - Returns: 二叉查找树
class func search(binaryTree: inout BinaryTree?, value: Int) -> BinaryTree? {
if binaryTree == nil {
return nil
}else {
if value < binaryTree!.value! {
//要查找的值小于节点的值,从左子树继续查找
return search(binaryTree: &binaryTree!.leftNode, value: value)
}else if value > binaryTree!.value! {
//要查找的值大于节点的值,从右子树继续查找
return search(binaryTree: &binaryTree!.rightNode, value: value)
}else {
//要查找的值等于节点的值
return binaryTree
}
}
}
- 前序遍历二叉树
/// 前序遍历二叉树
/// - Parameters:
/// - binaryTree: 二叉树
/// - handler: 返回遍历的节点
class func firstErgodic(binaryTree: BinaryTree?, handler: (_ node: BinaryTree) -> ()) {
if binaryTree != nil {
handler(binaryTree!)
self.firstErgodic(binaryTree: binaryTree?.leftNode, handler: handler)
self.firstErgodic(binaryTree: binaryTree?.rightNode, handler: handler)
}
}
- 中序遍历二叉树
/// 中序遍历二叉树
/// - Parameters:
/// - binaryTree: 二叉树
/// - handler: 返回遍历的节点
class func middleErgodic(binaryTree: BinaryTree?, handler: (_ node: BinaryTree) -> ()) {
if binaryTree != nil {
self.middleErgodic(binaryTree: binaryTree?.leftNode, handler: handler)
handler(binaryTree!)
self.middleErgodic(binaryTree: binaryTree?.rightNode, handler: handler)
}
}
- 后序遍历二叉树
/// 后序遍历二叉树
/// - Parameters:
/// - binaryTree: 二叉树
/// - handler: 返回遍历的节点
class func lastErgodic(binaryTree: BinaryTree?, handler: (_ node: BinaryTree) -> ()) {
if binaryTree != nil {
self.lastErgodic(binaryTree: binaryTree?.leftNode, handler: handler)
self.lastErgodic(binaryTree: binaryTree?.rightNode, handler: handler)
handler(binaryTree!)
}
}
- 层次遍历
/// 层次遍历(广度优先)
/// - Parameters:
/// - binaryTree: 二叉树
/// - handler: 返回遍历的节点
class func levelErgodic(binaryTree: BinaryTree?, handler: (_ node: BinaryTree) -> ()) {
if binaryTree == nil {
return
}
var array = Array<BinaryTree>.init()
array.append(binaryTree!)
while array.count > 0 {
let node = array.first
handler(node!)
//删除第一个节点
array.removeFirst()
if node?.leftNode != nil {
array.append(node!.leftNode!)
}
if node?.rightNode != nil {
array.append(node!.rightNode!)
}
}
}
- 二叉树的深度,深度从0开始
/// 二叉树的深度,深度从0开始
/// - Parameter binaryTree: 二叉树
/// - Returns: 二叉树的深度
class func depth(binaryTree: BinaryTree?) -> Int {
if binaryTree == nil {
return 0
}
if binaryTree?.leftNode == nil && binaryTree?.rightNode == nil {
//如果节点的左右节点都为空,深度为0
return 0
}
//左子树深度
let leftDepth = self.depth(binaryTree: binaryTree?.leftNode)
//右子树深度
let rightDepth = self.depth(binaryTree: binaryTree?.rightNode)
//二叉树的深度=max(左子树的深度,右子树的深度)+ 1
return max(leftDepth, rightDepth) + 1
}
- 二叉树的宽度
/// 二叉树的宽度
/// - Parameter binaryTree: 二叉树
/// - Returns: 二叉树的宽度
class func width(binaryTree: BinaryTree?) -> Int {
if binaryTree == nil {
return 0
}
var array = Array<BinaryTree>.init()
array.append(binaryTree!)
//最大宽度,初始化为1(因为已经有根节点)
var maxWidth = 1
//当前宽度
var curWidth = 1
while array.count > 0 {
curWidth = array.count
for _ in 0 ..< curWidth {
let node = array.first
array.removeFirst()
if node?.leftNode != nil {
array.append(node!.leftNode!)
}
if node?.rightNode != nil {
array.append(node!.rightNode!)
}
}
maxWidth = max(maxWidth, array.count)
}
return maxWidth
}