十五周算法训练营——二叉树遍历

今天是十五周算法训练营的第四周,主要讲二叉树遍历专题,包含:前序遍历、中序遍历、后续遍历、DFS、BFS。(欢迎加入十五周算法训练营,与小伙伴一起卷算法)

前序遍历

/**
 * 二叉树先序遍历
 * 
 * 遍历顺序:根——左——右
 * 
 * 前序位置的代码在刚刚进入一个二叉树节点的时候执行
 * 后续位置的代码在将要离开一个二叉树节点的时候执行
 * 中序位置的代码在一个二叉树节点左子树都遍历完,即将开始遍历右子树的时候执行
 * 这篇文章对前序位置、中序位置、后续位置的解释好好理解https://mp.weixin.qq.com/s?__biz=MzAxODQxMDM0Mw==&mid=2247496551&idx=1&sn=c6859fe37229a39e240a3b9323106bb4&scene=21#wechat_redirect
 */
function preOrderTraverse(head) {
    if (head == null) {
        return;
    }
    console.log(head.val);
    preOrderTraverse(head.left);
    preOrderTraverse(head.right);
}

// 对于先序遍历的非递归版,准备一个栈,然后将头压入栈中,循环弹出一个值,有右孩子的先压右孩子,再压左孩子
function preOrderTraverseUnRecur(head) {
    if (head == null) {
        return;
    }

    const stack = [];

    stack.push(head);

    while (stack.length > 0) {
        head = stack.pop();
        console.log(head.val);
        if (head.right != null) {
            stack.push(head.right);
        }

        if (head.left != null) {
            stack.push(head.left);
        }
    }
}

const binaryTree = {
    val: 10,
    left: {
        val: 8,
        right: {
            val: 9
        }
    },
    right: {
        val: 15
    }
};

preOrderTraverse(binaryTree);

preOrderTraverseUnRecur(binaryTree);

中序遍历

/**
 * 中续遍历
 * 
 * 遍历顺序:左——根——右
 */
function inOrderTraverse(head) {
    if (head == null) {
        return;
    }
    inOrderTraverse(head.left);

    console.log(head.val);

    inOrderTraverse(head.right);
}

/**
 * 非递归版本实现
 * 准备一个栈
 * 先将左节点全压入栈中
 * 当前节点为空,则从栈中拿一个打印,当前节点往右跑
 */
function inOrderTraverseUnRecur(head) {
    if (head == null) {
        return;
    }

    const stack = [];

    while (stack.length > 0 || head != null) {
        if (head != null) {
            stack.push(head);
            head = head.left;
        } else {
            head = stack.pop();
            console.log(head.val);
            head = head.right;
        }
    }
}

const binaryTree = {
    val: 10,
    left: {
        val: 8,
        right: {
            val: 9
        }
    },
    right: {
        val: 15
    }
};

inOrderTraverse(binaryTree);

inOrderTraverseUnRecur(binaryTree);

后续遍历

/**
 * 后续遍历
 * 
 * 遍历顺序:左——右——根
 */
function posOrderTraverse(head) {
    if (head == null) {
        return;
    }

    posOrderTraverse(head.left);
    posOrderTraverse(head.right);
    console.log(head.val);
}

// 对于后续遍历的非递归版,后续左-右-根,但我们可以根据根-右-左,然后将其存入一个栈中,弹出就是左-右-根
function posOrderTraverseUnRecur(head) {
    if (head == null) {
        return;
    }

    const stack = [];
    const stack1 = [];
    stack.push(head);
    while (stack.length > 0) {
        head = stack.pop();
        stack1.push(head.val);
        if (head.left != null) {
            stack.push(head.left);
        }

        if (head.right != null) {
            stack.push(head.right);
        }
    }

    while (stack1.length > 0) {
        console.log(stack1.pop());
    }
}

const binaryTree = {
    val: 10,
    left: {
        val: 8,
        right: {
            val: 9
        }
    },
    right: {
        val: 15
    }
};

posOrderTraverse(binaryTree);

posOrderTraverseUnRecur(binaryTree);

DFS

function DFS1(head) {
    if (head == null) {
        return;
    }

    console.log(head.val);
    DFS1(head.left);
    DFS1(head.right);
}

// 对于二叉树的深度优先就是二叉树的先序遍历,用一个栈实现
function DFS2(head) {
    if (head == null) {
        return;
    }

    const stack = [head];

    while (stack.length > 0) {
        head = stack.pop();
        console.log(head.val);

        if (head.right != null) {
            stack.push(head.right);
        }

        if (head.left != null) {
            stack.push(head.left);
        }
    }
}

const binaryTree = {
    val: 10,
    left: {
        val: 8,
        right: {
            val: 9
        }
    },
    right: {
        val: 15
    }
};

DFS1(binaryTree);

DFS2(binaryTree);

BFS

function BFS(head) {
    if (head == null) {
        return;
    }

    const list = [head];

    while (list.length > 0) {
        head = list.shift();
        console.log(head.val);

        if (head.left != null) {
            list.push(head.left);
        }

        if (head.right != null) {
            list.push(head.right);
        }
    }
}

const binaryTree = {
    val: 10,
    left: {
        val: 8,
        right: {
            val: 9
        }
    },
    right: {
        val: 15
    }
};

BFS(binaryTree);

67665a3193dbea6a1b918b5e0d9df05f.jpeg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值