Feature/array representation of tree swift (#649)

* refactor: encode & decode Tree

* style: build warning

* feat: add Swift codes for array_representation_of_tree article
This commit is contained in:
nuomi1
2023-07-24 12:46:48 +08:00
committed by GitHub
parent c1adeb2399
commit 9ab4b0b15c
12 changed files with 200 additions and 32 deletions
+2
View File
@@ -35,6 +35,7 @@ let package = Package(
.executable(name: "binary_tree", targets: ["binary_tree"]),
.executable(name: "binary_tree_bfs", targets: ["binary_tree_bfs"]),
.executable(name: "binary_tree_dfs", targets: ["binary_tree_dfs"]),
.executable(name: "array_binary_tree", targets: ["array_binary_tree"]),
.executable(name: "binary_search_tree", targets: ["binary_search_tree"]),
.executable(name: "avl_tree", targets: ["avl_tree"]),
// chapter_heap
@@ -120,6 +121,7 @@ let package = Package(
.executableTarget(name: "binary_tree", dependencies: ["utils"], path: "chapter_tree", sources: ["binary_tree.swift"]),
.executableTarget(name: "binary_tree_bfs", dependencies: ["utils"], path: "chapter_tree", sources: ["binary_tree_bfs.swift"]),
.executableTarget(name: "binary_tree_dfs", dependencies: ["utils"], path: "chapter_tree", sources: ["binary_tree_dfs.swift"]),
.executableTarget(name: "array_binary_tree", dependencies: ["utils"], path: "chapter_tree", sources: ["array_binary_tree.swift"]),
.executableTarget(name: "binary_search_tree", dependencies: ["utils"], path: "chapter_tree", sources: ["binary_search_tree.swift"]),
.executableTarget(name: "avl_tree", dependencies: ["utils"], path: "chapter_tree", sources: ["avl_tree.swift"]),
// chapter_heap
@@ -25,7 +25,7 @@ func preOrder(root: TreeNode?) {
enum PreorderTraversalICompact {
/* Driver Code */
static func main() {
let root = TreeNode.listToTree(list: [1, 7, 3, 4, 5, 6, 7])
let root = TreeNode.listToTree(arr: [1, 7, 3, 4, 5, 6, 7])
print("\n初始化二叉树")
PrintUtil.printTree(root: root)
@@ -30,7 +30,7 @@ func preOrder(root: TreeNode?) {
enum PreorderTraversalIICompact {
/* Driver Code */
static func main() {
let root = TreeNode.listToTree(list: [1, 7, 3, 4, 5, 6, 7])
let root = TreeNode.listToTree(arr: [1, 7, 3, 4, 5, 6, 7])
print("\n初始化二叉树")
PrintUtil.printTree(root: root)
@@ -33,7 +33,7 @@ func preOrder(root: TreeNode?) {
enum PreorderTraversalIIICompact {
/* Driver Code */
static func main() {
let root = TreeNode.listToTree(list: [1, 7, 3, 4, 5, 6, 7])
let root = TreeNode.listToTree(arr: [1, 7, 3, 4, 5, 6, 7])
print("\n初始化二叉树")
PrintUtil.printTree(root: root)
@@ -56,7 +56,7 @@ func backtrack(state: inout [TreeNode], choices: [TreeNode], res: inout [[TreeNo
enum PreorderTraversalIIITemplate {
/* Driver Code */
static func main() {
let root = TreeNode.listToTree(list: [1, 7, 3, 4, 5, 6, 7])
let root = TreeNode.listToTree(arr: [1, 7, 3, 4, 5, 6, 7])
print("\n初始化二叉树")
PrintUtil.printTree(root: root)
@@ -0,0 +1,141 @@
/**
* File: array_binary_tree.swift
* Created Time: 2023-07-23
* Author: nuomi1 (nuomi1@qq.com)
*/
import utils
/* 数组表示下的二叉树类 */
class ArrayBinaryTree {
private var tree: [Int?]
/* 构造方法 */
init(arr: [Int?]) {
tree = arr
}
/* 节点数量 */
func size() -> Int {
tree.count
}
/* 获取索引为 i 节点的值 */
func val(i: Int) -> Int? {
// 若索引越界,则返回 null ,代表空位
if i < 0 || i >= size() {
return nil
}
return tree[i]
}
/* 获取索引为 i 节点的左子节点的索引 */
func left(i: Int) -> Int {
2 * i + 1
}
/* 获取索引为 i 节点的右子节点的索引 */
func right(i: Int) -> Int {
2 * i + 2
}
/* 获取索引为 i 节点的父节点的索引 */
func parent(i: Int) -> Int {
(i - 1) / 2
}
/* 层序遍历 */
func levelOrder() -> [Int] {
var res: [Int] = []
// 直接遍历数组
for i in stride(from: 0, to: size(), by: 1) {
if let val = val(i: i) {
res.append(val)
}
}
return res
}
/* 深度优先遍历 */
private func dfs(i: Int, order: String, res: inout [Int]) {
// 若为空位,则返回
guard let val = val(i: i) else {
return
}
// 前序遍历
if order == "pre" {
res.append(val)
}
dfs(i: left(i: i), order: order, res: &res)
// 中序遍历
if order == "in" {
res.append(val)
}
dfs(i: right(i: i), order: order, res: &res)
// 后序遍历
if order == "post" {
res.append(val)
}
}
/* 前序遍历 */
func preOrder() -> [Int] {
var res: [Int] = []
dfs(i: 0, order: "pre", res: &res)
return res
}
/* 中序遍历 */
func inOrder() -> [Int] {
var res: [Int] = []
dfs(i: 0, order: "in", res: &res)
return res
}
/* 后序遍历 */
func postOrder() -> [Int] {
var res: [Int] = []
dfs(i: 0, order: "post", res: &res)
return res
}
}
@main
enum _ArrayBinaryTree {
/* Driver Code */
static func main() {
// 初始化二叉树
// 这里借助了一个从数组直接生成二叉树的函数
let arr = [1, 2, 3, 4, nil, 6, 7, 8, 9, nil, nil, 12, nil, nil, 15]
let root = TreeNode.listToTree(arr: arr)
print("\n初始化二叉树\n")
print("二叉树的数组表示:")
print(arr)
print("二叉树的链表表示:")
PrintUtil.printTree(root: root)
// 数组表示下的二叉树类
let abt = ArrayBinaryTree(arr: arr)
// 访问节点
let i = 1
let l = abt.left(i: i)
let r = abt.right(i: i)
let p = abt.parent(i: i)
print("\n当前节点的索引为 \(i) ,值为 \(abt.val(i: i) as Any)")
print("其左子节点的索引为 \(l) ,值为 \(abt.val(i: l) as Any)")
print("其右子节点的索引为 \(r) ,值为 \(abt.val(i: r) as Any)")
print("其父节点的索引为 \(p) ,值为 \(abt.val(i: p) as Any)")
// 遍历树
var res = abt.levelOrder()
print("\n层序遍历为:\(res)")
res = abt.preOrder()
print("前序遍历为:\(res)")
res = abt.inOrder()
print("中序遍历为:\(res)")
res = abt.postOrder()
print("后序遍历为:\(res)")
}
}
-2
View File
@@ -89,7 +89,6 @@ class AVLTree {
}
/* 插入节点 */
@discardableResult
func insert(val: Int) {
root = insertHelper(node: root, val: val)
}
@@ -116,7 +115,6 @@ class AVLTree {
}
/* 删除节点 */
@discardableResult
func remove(val: Int) {
root = removeHelper(node: root, val: val)
}
@@ -90,7 +90,6 @@ class BinarySearchTree {
}
/* 删除节点 */
@discardableResult
func remove(num: Int) {
// 若树为空,直接提前返回
if root == nil {
@@ -160,7 +159,7 @@ enum _BinarySearchTree {
PrintUtil.printTree(root: bst.getRoot())
/* 查找节点 */
var node = bst.search(num: 7)
let node = bst.search(num: 7)
print("\n查找到的节点对象为 \(node!),节点值 = \(node!.val)")
/* 插入节点 */
@@ -31,7 +31,7 @@ enum BinaryTreeBFS {
static func main() {
/* 初始化二叉树 */
// 这里借助了一个从数组直接生成二叉树的函数
let node = TreeNode.listToTree(list: [1, 2, 3, 4, 5, 6, 7])!
let node = TreeNode.listToTree(arr: [1, 2, 3, 4, 5, 6, 7])!
print("\n初始化二叉树\n")
PrintUtil.printTree(root: node)
@@ -48,7 +48,7 @@ enum BinaryTreeDFS {
static func main() {
/* 初始化二叉树 */
// 这里借助了一个从数组直接生成二叉树的函数
let root = TreeNode.listToTree(list: [1, 2, 3, 4, 5, 6, 7])!
let root = TreeNode.listToTree(arr: [1, 2, 3, 4, 5, 6, 7])!
print("\n初始化二叉树\n")
PrintUtil.printTree(root: root)
+1 -1
View File
@@ -79,7 +79,7 @@ public enum PrintUtil {
print("堆的数组表示:", terminator: "")
print(queue)
print("堆的树状表示:")
let root = TreeNode.listToTree(list: queue)
let root = TreeNode.listToTree(arr: queue)
printTree(root: root)
}
+49 -21
View File
@@ -4,40 +4,68 @@
* Author: nuomi1 (nuomi1@qq.com)
*/
/* 二叉树节点类 */
public class TreeNode {
public var val: Int // 节点值
public var height: Int // 节点高度
public var left: TreeNode? // 左子节点引用
public var right: TreeNode? // 右子节点引用
/* 构造方法 */
public init(x: Int) {
val = x
height = 0
}
public static func listToTree(list: [Int]) -> TreeNode? {
let size = list.count
if size == 0 {
// 序列化编码规则请参考:
// https://www.hello-algo.com/chapter_tree/array_representation_of_tree/
// 二叉树的数组表示:
// [1, 2, 3, 4, nil, 6, 7, 8, 9, nil, nil, 12, nil, nil, 15]
// 二叉树的链表表示:
// /——— 15
// /——— 7
// /——— 3
// | \——— 6
// | \——— 12
// ——— 1
// \——— 2
// | /——— 9
// \——— 4
// \——— 8
/* 将列表反序列化为二叉树:递归 */
private static func listToTreeDFS(arr: [Int?], i: Int) -> TreeNode? {
if i < 0 || i >= arr.count || arr[i] == nil {
return nil
}
let root = TreeNode(x: list[0])
var queue: [TreeNode] = [root]
var i = 0
while !queue.isEmpty {
let node = queue.removeFirst()
i += 1
if i >= size {
break
}
node.left = TreeNode(x: list[i])
queue.append(node.left!)
i += 1
if i >= size {
break
}
node.right = TreeNode(x: list[i])
queue.append(node.right!)
}
let root = TreeNode(x: arr[i]!)
root.left = listToTreeDFS(arr: arr, i: 2 * i + 1)
root.right = listToTreeDFS(arr: arr, i: 2 * i + 2)
return root
}
/* 将列表反序列化为二叉树 */
public static func listToTree(arr: [Int?]) -> TreeNode? {
listToTreeDFS(arr: arr, i: 0)
}
/* 将二叉树序列化为列表:递归 */
private static func treeToListDFS(root: TreeNode?, i: Int, res: inout [Int?]) {
if root == nil {
return
}
while i >= res.count {
res.append(nil)
}
res[i] = root?.val
treeToListDFS(root: root?.left, i: 2 * i + 1, res: &res)
treeToListDFS(root: root?.right, i: 2 * i + 2, res: &res)
}
/* 将二叉树序列化为列表 */
public static func treeToList(root: TreeNode?) -> [Int?] {
var res: [Int?] = []
treeToListDFS(root: root, i: 0, res: &res)
return res
}
}