数据结构------遍历二叉树的那些事

数据结构从大学学习之后,说实话忘记的差不多了,近期便在复习数据结构,刚好看到二叉树遍历这里了,想留下一下关于遍历二叉树的方法,以防楼主忘记,博文中用的语言为Swift.

创建的树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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值