【算法】代码随想录训练营Day13打卡,二叉树

满二叉树

二叉树只有枝为0或者为2的节点,并且枝为0的节点在同一层

如图

这种是为满二叉树
在这里插入图片描述

这种不是满二叉树

在这里插入图片描述

完全二叉树

完全二叉树就是叶节点只能出现在最下层或者次下层,最下面一层的结点都集中在该层最左边的若干位置的二叉树

在这里插入图片描述

二叉搜索树

前面介绍的树,都没有数值的,而二叉搜索树是有数值的了,二叉搜索树是一个有序树。

若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
它的左、右子树也分别为二叉排序树
下面这两棵树都是搜索树

在这里插入图片描述

平衡二叉搜索树

平衡二叉搜索树:又被称为AVL(Adelson-Velsky and Landis)树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

如图:
在这里插入图片描述

最后一棵 不是平衡二叉树,因为它的左右两个子树的高度差的绝对值超过了1。

二叉树遍历方式

二叉树只有两种遍历方式 即 广度优先遍历深度优先遍历

  • 深度优先遍历

    • 前序遍历(递归法,迭代法)
    • 中序遍历(递归法,迭代法)
    • 后序遍历(递归法,迭代法)
  • 广度优先遍历

    • 层次遍历(迭代法)
  • 前序遍历:中左右
  • 中序遍历:左中右
  • 后序遍历:左右中

递归遍历法

前序遍历
就是先push 再递归左右树

var preorderTraversal = function(root) {
 let res=[];
 const dfs=function(root){
     if(root===null)return ;
     //先序遍历所以从父节点开始
     res.push(root.val);
     //递归左子树
     dfs(root.left);
     //递归右子树
     dfs(root.right);
 }
 //只使用一个参数 使用闭包进行存储结果
 dfs(root);
 return res;
};

中序遍历
就是先递归左树 再push 再递归右树

var inorderTraversal = function(root) {
    let res=[];
    const dfs=function(root){
        if(root===null){
            return ;
        }
        dfs(root.left);
        res.push(root.val);
        dfs(root.right);
    }
    dfs(root);
    return res;
};

后序遍历
就是先遍历左树 再遍历右树再push

var inorderTraversal = function(root) {
   let res=[];
   const dfs=function(root){
       if(root===null){
           return ;
       }
       dfs(root.left);
       dfs(root.right);
       res.push(root.val);
   }
   dfs(root);
   return res;
};

迭代法

前序遍历
前序遍历的迭代法用栈就可以实现,我们先将头节点放入栈中,然后每个节点出栈的时候,先入栈其右子节点,再入栈左子节点就可以了

var preorderTraversal = function(root) {
		const res = [];
		if (root == null) return res;
		const stack = [root];
		while(stack.length != 0){
		let item = stack.pop();
		res.push(item.val);
		if(item.right) stack.push(item.right);
		if(item.left) stack.push(item.left);
	};
	return res;
		

}

中序遍历
其实用一个栈也能做出来,
我们只需要先从头节点开始,把最左边的节点全部压进栈,然后我们每出栈一个节点就去遍历他右节点的左节点,重复上面的操作

const inorderTraversal = (root) => {
  const res = [];
  const stack = [];

  while (root) {        // 能压栈的左子节点都压进来
    stack.push(root);
    root = root.left;
  }
  while (stack.length) {
    let node = stack.pop(); // 栈顶的节点出栈
    res.push(node.val);     // 在压入右子树之前,处理它的数值部分(因为中序遍历)
    node = node.right;      // 获取它的右子树
    while (node) {          // 右子树存在,执行while循环    
      stack.push(node);     // 压入当前root
      node = node.left;     // 不断压入左子节点
    }
  }
  return res;
}

后续遍历
再来看后序遍历,先序遍历是中左右,后续遍历是左右中,那么我们只需要调整一下先序遍历的代码顺序,就变成中右左的遍历顺序,然后在反转result数组,输出的结果顺序就是左右中了,如下图:
在这里插入图片描述

var inorderTraversal = function(root) {
 		const res = [];
		if (root == null) return res;
		const stack = [root];
		while(stack.length != 0){
		let item = stack.pop();
		res.push(item.val);
		if(item.left) stack.push(item.left);
		if(item.right) stack.push(item.right);
		};
	
		return res.reverse();
};
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值