二叉树及其遍历

91 阅读3分钟

前言

今天我们来聊聊二叉树这种数据结构并且实现它的三种遍历

二叉树

二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个节点最多只能有两棵子树,且有左右之分。

二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个节点 。

QQ截图20240627233739.png

注意:

1.空树也可称为二叉树

2.非空树必须由根结点,左子树,右子树组成,且左右子树都是二叉树

遍历

1.先序遍历--根左右

[我们以力扣144为例](144. 二叉树的前序遍历 - 力扣(LeetCode))

image.png

结果为:[1,2,3]

用递归的方法:

function preorderTraversal(root){
      let res=[];
      function preorder(node){
          if(node){
          res.push(node.val)
          preorder(node.left)
          proorder(node.right)
          }
      }
      preorder(root)
      return res;
}

递归就是自己调用自己,第4行先进行判断是否为空,若不为空则把该结点放入空数组,递归左结点,右结点。

迭代法:

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

    return res
}

我们先假设有这样一个树

qq_pic_merged_1719504655395.jpg

先序遍历的结果是:[1,2,4,5,3,6]

用栈怎么解决呢?我们可以这样:结点1先入栈,判断栈是否有值如果有出栈,判断如果结点1存在右结点,右结点3入栈,左结点2入栈。结点2出栈,判断如果存在右结点,右结点5入栈,左结点4入栈。结点4出栈判断是否有右结点,没有继续出栈结点5, 结点3出栈,有右结点6,右结点入栈,右结点6出栈

2.中序遍历 ---左根右

结果·:[4,2,5,1,3,6]

递归法:

function inorderTraversal(root){
    const res=[]
    function inorder(node){
       inorder(node.left)
       res.push(node.val)
       inorder(node.right)
    }
    inorder(root);
    return res;
}

迭代:

var inorderTraversal = function(root) {
    if(root == null) return []
    let res = []
    let stack = []
   let cur = root

    while(stack.length || cur){
        while(cur){
            stack.push(cur)
            cur = cur.left
        }
        cur = stack.pop()
        res.push(cur.val)
        cur = cur.right
    }
    return res
}

这里有点难度:还是上面那个树。先读到根节点1入栈,让一个变量存放根结点的左结点,此时为2,将2入栈,这变量为4,4没有左结点出栈,2出栈,5入栈,没有左结点,5出栈,1出栈,1有右结点,3入栈,3没有左结点出栈,3有右结点6,6出栈,6没有子结点,结束。

后序遍历---左右根

结果:[4,5,2,6,3,1]

递归:

function postorderTraversal(root){
       const res=[];
       function postorder(node){
           if(node){
           postorder(node.left);
           postorder(node.right);
           res.push(node.val);
           }
           }
        postorder(root)   
        return res;
}

迭代:

var postorderTraversal = function(root) {
    if(!root) return []
    const res = [];
    const stack=[];
    stack.push(root)
    
    while(stack.length){
       const cur=stack.pop()
       res.unshift(cur.val)
       if(cur.left){
           stack.push(cur.left)
       }
       if(cur.right){
           stack.push(cur.right)
       }
        
    }
    return res;
}

后序遍历和前序遍历类似,还是那棵树:根结点1入栈,1出栈,左右结点分别入栈,结点3出栈,结点3有右子结点6入栈,6没有左右结点出栈,2接着出栈,4,5入栈,5没有子结点出栈,4没有子结点出栈.出栈元素全都放入数组头部,得到最后结果。

总结

今天我们聊了有关二叉树的知识并且刷了几道力扣算法题,最后希望大家好好学习,天天向上吧。