数据结构------遍历二叉树的那些事
2016-11-10 10:05
162 查看
数据结构从大学学习之后,说实话忘记的差不多了,近期便在复习数据结构,刚好看到二叉树遍历这里了,想留下一下关于遍历二叉树的方法,以防楼主忘记,博文中用的语言为Swift.
创建的树TreeNode结点结构如下:
通常遍历的方法是使用递归方式遍历二叉树,但为了整合一下之前看到的栈与队列,所以也记录一下使用栈遍历数的方法:
结构如下:
创建的树TreeNode结点结构如下:
/// 树节点 class TreeNode { var val : Int //数值 var left : TreeNode? //左子树 var right : TreeNode? //右子树 init(_ val : Int) { self.val = val self.left = nil self.right = nil } }
通常遍历的方法是使用递归方式遍历二叉树,但为了整合一下之前看到的栈与队列,所以也记录一下使用栈遍历数的方法:
使用栈遍历树
栈-前序
/// 用栈实现前序遍历 func preorderTraversal(root: TreeNode?) -> [Int] { var res = [Int]() var stack = [TreeNode]() var node = root //如果栈不为空 或者 节点不是 nil while !stack.isEmpty || node != nil { //如果结点不为nil if node != nil { res.append(node!.val) //数据栈中添加数据 stack.append(node!) //结点栈中添加结点 node = node!.left //指向左结点 }else{ //如果结点为nil,node指向最后一个根节点的右子树 node = stack.removeLast().right } } return res }
栈-中序
/// 用栈实现中序遍历 func inorderTraversal(root: TreeNode?) -> [Int] { var res = [Int]() var stack = [TreeNode]() var node = root // 如果栈不是空 并且 结点不是nil while !stack.isEmpty || node != nil { //如果结点不是nil if node != nil { stack.append(node!) node = node!.left }else { //存放数据 res.append(stack.last!.val) node = stack.removeLast().right } } return res }
栈-后序
/// 用栈实现后序遍历 func posorderTraversal(root: TreeNode?) -> [Int] { var res = [Int]() var stack = [TreeNode]() let node = root stack.append(node!) //如果栈不为空 while !stack.isEmpty { let nodeTemp = stack.removeLast() res.append(nodeTemp.val) if nodeTemp.left != nil { stack.append(nodeTemp.left!); } if nodeTemp.right != nil { stack.append(nodeTemp.right!); } } return res.reversed() }
使用递归遍历树
递归遍历算是比较无脑的一种,也是最基础的一种,这里不是说递归不好,毕竟在动态规划以及分治上还有很有作用的,写法基本一致,只是顺序不一样罢了./// 递归实现前序遍历 func preOrderTraversal(root: TreeNode?,_ res:inout [Int]) { if root != nil { res.append((root?.val)!) preOrderTraversal(root: root?.left,&res) preOrderTraversal(root: root?.right,&res) } } /// 递归实现中序遍历 func inOrderTraversal(root: TreeNode?, _ res:inout [Int]) { if(root != nil) { inOrderTraversal(root: root?.left, &res) res.append(root!.val) inOrderTraversal(root: root?.right, &res) } } ///递归实现后序遍历 func postOrderTravelsal(root: TreeNode?, _ res:inout [Int]) { if root != nil { postOrderTravelsal(root: root?.left, &res) postOrderTravelsal(root: root?.right, &res) res.append(root!.val) } }
测试
构建一棵二叉树
当然真正的构建二叉树绝对不是这么笨的办法,但仅仅是为了测试而已 , 所有请不要吐槽 = =//初始化一棵树 var root = TreeNode(1) //创建子树 var tree3 = TreeNode(3) var tree8 = TreeNode(8) var tree5 = TreeNode(5) var tree9 = TreeNode(9) var tree2 = TreeNode(2) var tree7 = TreeNode(7) var tree10 = TreeNode(10) //拼接 tree5.right = tree9 tree3.right = tree5 tree3.left = tree8 tree7.right = tree10 tree2.right = tree7 root.left = tree3 root.right = tree2
结构如下:
1 -> 3,2 3 -> 8,5 8 -> #,# 5 -> #,9 9 -> #,# 2 -> #,7 7 -> #,10 10 -> #,#
测试结果
//进行测试 print("栈 遍历:") print("先序:\(preorderTraversal(root: root))") print("中序:\(inorderTraversal(root: root))") print("后序:\(posorderTraversal(root: root))") print("递归 遍历:") var preOrder = [Int]() preOrderTraversal(root: root,&preOrder) print("先序:\(preOrder)") var inOrder = [Int]() inOrderTraversal(root: root, &inOrder) print("中序:\(inOrder)") var postOrder = [Int]() postOrderTravelsal(root: root, &postOrder) print("后序:\(postOrder)")
栈 遍历: 先序:[1, 3, 8, 5, 9, 2, 7, 10] 中序:[8, 3, 5, 9, 1, 2, 7, 10] 后序:[8, 9, 5, 3, 10, 7, 2, 1] 递归 遍历: 先序:[1, 3, 8, 5, 9, 2, 7, 10] 中序:[8, 3, 5, 9, 1, 2, 7, 10] 后序:[8, 9, 5, 3, 10, 7, 2, 1] Program ended with exit code: 0
相关文章推荐
- 第十周 数据结构例程——二叉树的层次遍历算法
- 21-数据结构_链式二叉树-遍历实现
- 每天一点数据结构之二叉树非递归遍历
- 数据结构学习-二叉树-链式结构、特殊二叉树、性质、遍历、遍历应用
- 【算法与数据结构】二叉树的 后序 遍历
- 数据结构之遍历二叉树
- 【数据结构】二叉树的层次遍历2
- 数据结构与算法学习之二叉树的遍历:已知先序、中序、后序序列三者中的两种求另外一种遍历的算法
- 输入一组整数后用c语言数据结构对其进行大小比较以二叉树存储、遍历
- 【数据结构】一颗二叉树的中序遍历和前序遍历,求后序遍历
- 数据结构 - 二叉树(重构 + 遍历)
- 数据结构--二叉树代码实现(建立,前序,中序,后续遍历,树的深度,销毁)
- 数据结构 c语言实现 二叉树的层次遍历(linux下实现)
- 数据结构--二叉树的遍历--统计二叉树中叶子结点的个数(先序遍历)
- 【数据结构】二叉树的遍历
- 数据结构-二叉树的遍历(类C语言描写叙述)
- 数据结构 学习笔记(四):树(上):树的表示,二分查找,二叉树,先中后层次遍历
- 【数据结构】二叉树的构建及其遍历(C++实现)
- 【郝斌数据结构自学笔记】70-74_已知两种遍历序列求原始二叉树概述_已知先序和中序求后序_已知中序和后序求先序_树的应用简单介绍
- 数据结构之二叉树(遍历、建立、深度)