二叉树的递归算法

二叉树

二叉树是一种特殊的数据结构,有一个根节点,根节点下面有一左一右两个子节点,每个子节点又有各自的子节点,层层深入成树状。

二叉树的遍历

关于二叉树的遍历我只学习了递归遍历,非递归遍历比较复杂还是很理解。

递归遍历分为先序,中序和后序。用三个字母表示递归遍历可以很好理解:

D: 访问根节点,L: 遍历根节点的左子树,R:遍历根节点的右子树。

先序遍历:DLR

中序遍历:LDR

后序遍历:LRD

先序遍历的递归算法
function preOrder(node) {
    if (node) {
        console.log(node.value);
        preOrder(node.left);
        preOrder(node.right);
    }
}
中序遍历的递归算法
function inOrder(node) {
    if (node) {
        inOrder(node.left);
        console.log(node.value);
        inOrder(node.left);
    }
}
后序遍历的递归算法
function postOrder(node) {
    if (node) {
        postOrder(node.left);
        postOrder(node.right);
        console.log(node.value);
    }
}

更详细的二叉树算法可以查看这篇文章

定时问题

遇到的一个难题是如何实现间隔一段时间(500ms)改变节点的颜色,这就需要用到setTimeout()这个方法。刚开始的想法是把定时函数写进递归函数里面,让每次递归都执行setTimeout(),但是这个方法行不通,会改变每个节点出现的顺序,而且函数执行结束的时间小于定时时间,导致想要达到的效果一瞬间全部执行完毕,而不是按规定的时间一个一个出现,这个理解可能有点错误,但是没办法达到想要的效果,所以放弃。

我的方法是把遍历出来的值放进数组里,然后再用数组完成想要做的各种操作。

function preOrder(node) {
    if (node) {
        preOrder(node.left);
        preOrder(node.right);
        preList.push(node.value);
    }
}

for (let i = 0; i < preList.length; i++) {
    setTimeout(function() {
        console.log(preList[i]);  // 这样就可以按顺序每隔一段时间打印出一个数字
    }, 500 * i);
}

博客首发地址:https://www.jianshu.com/u/13cd86311525

二叉树是一种常见的数据结构,在递归算法中也有很多应用。创建二叉树递归算法可以分为前序遍历和中序遍历两种方式。 前序遍历方式下,我们按照“根-左-右”的顺序来构建二叉树。具体步骤如下: 1. 如果输入的节点值为null,则返回空节点。 2. 创建一个新的节点,将其值设置为当前的节点值。 3. 递归调用函数,将左子树的根节点设置为当前节点的左子节点。 4. 递归调用函数,将右子树的根节点设置为当前节点的右子节点。 5. 返回当前节点。 中序遍历方式下,我们按照“左-根-右”的顺序来构建二叉树。具体步骤如下: 1. 如果输入的节点值为null,则返回空节点。 2. 递归调用函数,将左子树的根节点设置为当前节点的左子节点。 3. 创建一个新的节点,将其值设置为当前的节点值。 4. 递归调用函数,将右子树的根节点设置为当前节点的右子节点。 5. 返回当前节点。 下面是一个示例代码,以前序遍历方式为例: ``` class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } public class Solution { public TreeNode buildTree(int[] preorder, int[] inorder) { return build(preorder, inorder, 0, preorder.length - 1, 0, inorder.length - 1); } private TreeNode build(int[] preorder, int[] inorder, int preStart, int preEnd, int inStart, int inEnd) { if (preStart > preEnd || inStart > inEnd) { return null; } int rootVal = preorder[preStart]; int index = 0; for (int i = inStart; i <= inEnd; i++) { if (inorder[i] == rootVal) { index = i; break; } } TreeNode root = new TreeNode(rootVal); root.left = build(preorder, inorder, preStart + 1, preStart + index - inStart, inStart, index - 1); root.right = build(preorder, inorder, preStart + index - inStart + 1, preEnd, index + 1, inEnd); return root; } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值