二叉树的三种遍历,前序遍历、中序遍历和后序遍历 - lua

3 篇文章 0 订阅
2 篇文章 0 订阅

三种遍历方式仅存在遍历节点顺序的不同而已

1、前序遍历 preOrder 遍历顺序:根节点->左子树->右子树

2、中序遍历 inOrder 遍历顺序:左子树->根节点->右子树

3、后序遍历 afterOrder 遍历顺序:左子树->右子树-->根节点

二叉树如图:

前序遍历:1  24  35

中序遍历:42  1  35

后序遍历:42  53  1

此处通过lua中的表实现二叉树结构:

local root = {
    [1] = {left = 2, right = 3, value = 1},
    [2] = {left = 4, value = 2},
    [3] = {right = 5, value = 3},
    [4] = {value = 4},
    [5] = {value = 5},
}

一、递归 recursion

前序遍历 preOrder 根节点->左子树->右子树

-- 1、递归 recursion
local function preOrder_recursion(root)
    -- body
    local ret = {}
    local function preOrder(node, ret)
        -- body
        if not node then
            return ret
        end
        ret[#ret+1] = node.value
        preOrder(root[node.left], ret)
        preOrder(root[node.right], ret)
        return ret
    end
    preOrder(root[1], ret)
    return ret
end

中序遍历 inOrder 左子树->根节点->右子树

-- 1、递归 recursion
local function inOrder_recursion(root)
    -- body
    local ret = {}
    local function inOrder(node, ret)
        -- body
        if not node then
            return ret
        end
        inOrder(root[node.left], ret)
        ret[#ret+1] = node.value
        inOrder(root[node.right], ret)
        return ret
    end
    inOrder(root[1], ret)
    return ret
end

后序遍历 afterOrder 左子树->右子树-->根节点

-- 1、递归 recursion
local function afterOrder_recursion(root)
    -- body
    local ret = {}
    local function afterOrder(node, ret)
        -- body
        if not node then
            return ret
        end
        afterOrder(root[node.left], ret)
        afterOrder(root[node.right], ret)
        ret[#ret+1] = node.value
        return ret
    end
    afterOrder(root[1], ret)
    return ret
end

 

二、迭代 iteration

前序遍历 preOrder 根节点->左子树->右子树

-- 2、迭代 iteration
local function preOrder_iteration(root)
    -- body
    local ret, stack = {}, {1}
    if not root then
        return ret
    end
    while next(stack) do
        local node = root[stack[#stack]]
        if #stack == 1 then
            stack = {}
        else
            stack[#stack] = nil
        end
        ret[#ret+1] = node.value
        if node.right then
            stack[#stack+1] = node.right
        end
        if node.left then
            stack[#stack+1] = node.left
        end
    end
    return ret
end

中序遍历 inOrder 左子树->根节点->右子树

-- 2、迭代 iteration
local function inOrder_iteration(root)
    -- body
    local ret, stack = {}, {}
    if not root then return ret end
    local node = root[1]
    while node ~= nil or #stack~=0 do
        while node ~= nil do
            stack[#stack+1] = node.value
            node = root[node.left]
        end
        node = root[stack[#stack]]
        if #stack == 1 then
            stack = {}
        else
            stack[#stack] = nil
        end
        ret[#ret+1] = node.value
        node = root[node.right]
    end
    return ret
end

后序遍历 afterOrder 左子树->右子树-->根节点

思路讲解:https://leetcode-cn.com/problems/binary-tree-postorder-traversal/solution/er-cha-shu-de-hou-xu-bian-li-by-leetcode/

-- 2、迭代 iteration 逆向思维
local function afterOrder_iteration(root)
    -- body
    local ret, stack = {}, {1}
    if not root then return ret end
    while #stack~=0 do
        -- 反向求解 逆序压栈
        local node = root[stack[#stack]]
        ret[#ret+1] = node.value
        if #stack == 1 then
            stack = {}
        else
            stack[#stack] = nil
        end
        if root[node.left] ~= nil then stack[#stack+1] = root[node.left].value end
        if root[node.right] ~= nil then stack[#stack+1] = root[node.right].value end
    end

    local function BackOrder_Tab(a)
        -- body
        local b = {}
        for k=1,#a do
            b[k] = a[#a - k + 1]
        end
        return b
    end

    -- 逆序输出
    return BackOrder_Tab(ret)
end

复杂度分析

时间复杂度:

递归:O(n)

迭代:O(n)

空间复杂度:

递归:最坏O(n),平均O(log n)

迭代:O(n)

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值