二叉树基本操作之深度遍历(前序、中序、后序)-js版

本文详细介绍了一个基于Java实现的树类,包括层序插入方法、递归和非递归遍历(先序、中序和后序)。展示了如何构造树并进行基本操作,适合初学者理解树结构和算法应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 * 节点类
 */
class TreeNode {
  constructor (val) {
    this.val = val
    this.left = null
    this.right = null
  }
}

/**
 * 树类
 */
class Tree {
  constructor () {
    this.root = null
  }

  /**
   * 层序按顺序插入
   * @param {*} val
   * @returns
   */
  insert (val) {
    const node = new TreeNode(val)
    if (!this.root) {
      this.root = node
      return true
    }
    const queue = [] // 队列
    queue.push(this.root)
    while (queue.length > 0) {
      const curNode = queue.shift() // 出队列
      if (curNode.left) { // 有左孩子,左孩子入队列,否则新节点就是左孩子
        queue.push(curNode.left)
      } else {
        curNode.left = node
        break
      }
      if (curNode.right) { // 有右孩子,右孩子入队列,否则新节点就是右孩子
        queue.push(curNode.right)
      } else {
        curNode.right = node
        break
      }
    }
  }

  /**
   * 先序遍历-递归
   * @param {*} node
   */
  recrusionPreorder (node) {
    console.log(node.val)
    if (node.left) {
      this.recrusionPreorder(node.left)
    }
    if (node.right) {
      this.recrusionPreorder(node.right)
    }
  }

  /**
   * 中序遍历-递归
   * @param {*} node
   */
  recrusionMesorder (node) {
    if (node.left) {
      this.recrusionMesorder(node.left)
    }
    console.log(node.val)
    if (node.right) {
      this.recrusionMesorder(node.right)
    }
  }

  /**
   * 后序遍历-递归
   */
  recrusionHouxu (node) {
    if (node.left) {
      this.recrusionHouxu(node.left)
    }
    if (node.right) {
      this.recrusionHouxu(node.right)
    }
    console.log(node.val)
  }

  /**
   * 先序-非递归
   */
  xianXu () {
    const stack = []
    stack.push(this.root)
    while (stack.length > 0) {
      const node = stack.pop()
      console.log(node.val)
      if (node.right) {
        stack.push(node.right)
      }
      if (node.left) {
        stack.push(node.left)
      }
    }
  }

  /**
   * 中序-非递归
   */
  zhongXu () {
    const stack = []
    let tmp = this.root
    while (stack.length > 0 || tmp) {
      if (tmp) {
        // tmp不为空就入栈
        stack.push(tmp)
        tmp = tmp.left
      } else {
        // 出栈
        const node = stack.pop()
        console.log(node.val)
        tmp = node.right
      }
    }
  }

  /**
   * 后序-非递归(将先序左右节点的入栈顺序调换,最后反转结果)
   */

  houxu () {
    const stack = []
    stack.push(this.root)
    let arr = []
    while (stack.length > 0) {
      const node = stack.pop()
      arr.push(node.val)
      if (node.left) {
        stack.push(node.left)
      }
      if (node.right) {
        stack.push(node.right)
      }
    }
    arr = arr.reverse()
    arr.forEach((item) => {
      console.log(item)
    })
  }

  /**
   * 后序-非递归
   */
  houxu1 () {
    const stack = []
    let p = this.root
    let last = null
    while (p || stack.length > 0) {
      if (p) {
        stack.push(p)
        p = p.left
      } else {
        p = stack.pop()
        if (p.right === last || !p.right) {
          // 若上一个被访问节点为该节点的右孩子,表明该节点有孩子已被访问过,则访问该节点
          console.log(p.val)
          last = p
          p = null
        } else {
          // 重新入栈
          stack.push(p)
          p = p.right
        }
      }
    }
  }
}


// 使用
const tree1 = new Tree()
      tree1.insert('a')
      tree1.insert('b')
      tree1.insert('c')
      tree1.insert('d')
      tree1.insert('e')
      tree1.insert('f')
      tree1.insert('g')
      tree1.insert('h')
      tree1.insert('i')
      tree1.insert('j')
      tree1.insert('k')
      tree1.insert('l')
      tree1.insert('m')
      console.log(tree1)
      console.log('***递归先序:')
      tree1.recrusionPreorder(tree1.root)
      console.log('***递归中序:')
      tree1.recrusionMesorder(tree1.root)
      console.log('***递归后序:')
      tree1.recrusionHouxu(tree1.root)
      console.log('先序:')
      tree1.xianXu()
      console.log('中序:')
      tree1.zhongXu()
      console.log('后序:')
      tree1.houxu()
      console.log('后序1:')
      tree1.houxu1()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值