广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript二叉树及各种遍历算法详情
  • 830
分享到

JavaScript二叉树及各种遍历算法详情

2024-04-02 19:04:59 830人浏览 八月长安
摘要

目录什么是二叉树满二叉树完全二叉树二叉树的存储数组存储链表存储与二叉树相关的算法深度优先遍历广度优先遍历先序遍历中序遍历后序遍历前言: 上一篇文章中介绍了树的概念、深度优先遍历和广度

前言:

上一篇文章中介绍了树的概念、深度优先遍历和广度优先遍历,这篇文章我们来学习一个特殊的树——二叉树。

什么是二叉树

二叉树是每个节点最多只能有两个子节点的树,如下图所示:

一个二叉树具有以下几个特质:

  • i层的节点最有只有2^(i-1)个;
  • 如果这颗二叉树的深度为k,那二叉树最多有2^k-1个节点;
  • 在一个非空的二叉树中,若使用n0表示叶子节点的个数,n2是度为2的非叶子节点的个数,那么两者满足关系n0 = n2 + 1

满二叉树

如果在一个二叉树中,除了叶子节点,其余的节点的每个度都是2,则说明该二叉树是一个满二叉树

如下图所示:

满二叉树除了满足普通二叉树特质,还具有如下几个特质:

  • 满二叉树的的第n层具有2^(n-1)个节点;
  • 深度为k的满二叉树一定存在2^k-1个节点,叶子节点的个数为2^(k-1)
  • 具有n个节点的满二叉树的深度为log_2^(n+1)

完全二叉树

如果一个二叉树去掉最后一次层是满二叉树,且最后一次的节点是依次从左到右分布的,则这个二叉树是一个完全二叉树,

如下图所示:

二叉树的存储

存储二叉树的常见方式分为两种,一种是使用数组存储,另一种使用链表存储。

数组存储

使用数组存储二叉树,如果遇到完全二叉树,存储顺序从上到下,从左到右,如下图所示:

如果是一个非完全二叉树,如下图所示:

需要先将其转换为完全二叉树,然后在进行存储,如下图所示:

可以很明显的看到存储空间的浪费。

链表存储

使用链表存储通常将二叉树中的分为3个部分,如下图:

这三个部分依次是左子树的引用,该节点包含的数据,右子树的引用,存储方式如下图所示:

与二叉树相关的算法

以下算法中遍历用到的树如下

// tree.js
const bt = {
  val: 'A',
  left: {
    val: 'B',
    left: { val: 'D', left: null, right: null },
    right: { val: 'E', left: null, right: null },
  },
  right: {
    val: 'C',
    left: {
      val: 'F',
      left: { val: 'H', left: null, right: null },
      right: { val: 'I', left: null, right: null },
    },
    right: { val: 'G', left: null, right: null },
  },
}
module.exports = bt

深度优先遍历

二叉树的深度优先遍历与树的深度优先遍历思路一致,思路如下:

  • 访问根节点;
  • 访问根节点的left
  • 访问根节点的right
  • 重复执行第二三步

实现代码如下:

const bt = {
  val: 'A',
  left: {
    val: 'B',
    left: { val: 'D', left: null, right: null },
    right: { val: 'E', left: null, right: null },
  },
  right: {
    val: 'C',
    left: {
      val: 'F',
      left: { val: 'H', left: null, right: null },
      right: { val: 'I', left: null, right: null },
    },
    right: { val: 'G', left: null, right: null },
  },
}

function dfs(root) {
  if (!root) return
  console.log(root.val)
  root.left && dfs(root.left)
  root.right && dfs(root.right) 
}
dfs(bt)

广度优先遍历

实现思路如下:

  • 创建队列,把根节点入队
  • 把对头出队并访问
  • 把队头的leftright依次入队
  • 重复执行2、3步,直到队列为空

实现代码如下:

function bfs(root) {
  if (!root) return
  const queue = [root]
  while (queue.length) {
    const node = queue.shift()
    console.log(node.val)
    node.left && queue.push(node.left)
    node.right && queue.push(node.right)
  }
}
bfs(bt)

先序遍历

二叉树的先序遍历实现思想如下:

  • 访问根节点;
  • 对当前节点的左子树进行先序遍历;
  • 对当前节点的右子树进行先序遍历;

如下图所示:

递归方式实现如下:

const bt = require('./tree')

function preorder(root) {
  if (!root) return
  console.log(root.val)
  preorder(root.left)
  preorder(root.right)
}
preorder(bt)

迭代方式实现如下:

// 非递归版
function preorder(root) {
  if (!root) return
  // 定义一个栈,用于存储数据
  const stack = [root]
  while (stack.length) {
    const node = stack.pop()
    console.log(node.val)
    
    node.right && stack.push(node.right)
    node.left && stack.push(node.left)
  }
}
preorder(bt)

中序遍历

二叉树的中序遍历实现思想如下:

  • 对当前节点的左子树进行中序遍历;
  • 访问根节点;
  • 对当前节点的右子树进行中序遍历;

如下图所示:

递归方式实现如下:

const bt = require('./tree')

// 递归版
function inorder(root) {
  if (!root) return
  inorder(root.left)
  console.log(root.val)
  inorder(root.right)
}
inorder(bt)

迭代方式实现如下:

// 非递归版
function inorder(root) {
  if (!root) return
  const stack = []
  // 定义一个指针
  let p = root
  // 如果栈中有数据或者p不是null,则继续遍历
  while (stack.length || p) {
    // 如果p存在则一致将p入栈并移动指针
    while (p) {
      // 将 p 入栈,并以移动指针
      stack.push(p)
      p = p.left
    }

    const node = stack.pop()
    console.log(node.val)
    p = node.right
  }
}
inorder(bt)

后序遍历

二叉树的后序遍历实现思想如下:

  • 对当前节点的左子树进行后序遍历;
  • 对当前节点的右子树进行后序遍历;
  • 访问根节点;

如下图所示:

递归方式实现如下:

const bt = require('./tree')

// 递归版
function postorder(root) {
  if (!root) return
  postorder(root.left)
  postorder(root.right)
  console.log(root.val)
}
postorder(bt)

迭代方式实现如下:

// 非递归版
function postorder(root) {
  if (!root) return
  const outputStack = []
  const stack = [root]
  while (stack.length) {
    const node = stack.pop()
    outputStack.push(node)
    // 这里先入left需要保证left后出,在stack中后出,就是在outputStack栈中先出
    node.left && stack.push(node.left)
    node.right && stack.push(node.right)
  }
  while (outputStack.length) {
    const node = outputStack.pop()
    console.log(node.val)
  }
}
postorder(bt)

到此这篇关于javascript二叉树及各种遍历算法详情的文章就介绍到这了,更多相关JavaScript二叉树内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: JavaScript二叉树及各种遍历算法详情

本文链接: https://www.lsjlt.com/news/164164.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript二叉树及各种遍历算法详情
    目录什么是二叉树满二叉树完全二叉树二叉树的存储数组存储链表存储与二叉树相关的算法深度优先遍历广度优先遍历先序遍历中序遍历后序遍历前言: 上一篇文章中介绍了树的概念、深度优先遍历和广度...
    99+
    2022-11-13
  • C++二叉树的创建及遍历详情
    目录树的定义什么是树?非递归的中序遍历的实现二叉树的非递归的前序遍历的实现二叉树的创建以及前中后序遍历的代码总结树的定义 什么是树? 假如给我们一棵二叉树的前序遍历和中序遍历结果,我...
    99+
    2022-11-13
  • JavaScript二叉树及遍历算法实例分析
    这篇“JavaScript二叉树及遍历算法实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看...
    99+
    2022-10-19
  • Java二叉树的四种遍历方式详解
    二叉树的四种遍历方式: 二叉树的遍历(traversing binary tree)是指从根结点出发,按照某种次序依次访问二叉树中所有的结点,使得每个结点被访问依次且仅被访...
    99+
    2022-11-12
  • JavaMorris遍历算法及其在二叉树中的应用
    目录一.Morris遍历1.什么是Morris遍历2.基本思想3.Morris遍历的优点和缺点4.二叉树的线索化二.中序Morris遍历1.中序Morris遍历的分析2.中序Morr...
    99+
    2023-05-18
    Java Morris遍历算法 Java Morris遍历
  • C++实现二叉树非递归遍历算法详解
    目录一、二叉树的前序遍历二、二叉树的中序遍历三、二叉树的后序遍历3.1 方法一3.2 方法二一、二叉树的前序遍历 题目链接 我们可以把任何一棵树看成左路节点,左路节点和右子树。先访问...
    99+
    2023-05-17
    C++二叉树非递归遍历 C++非递归遍历 C++二叉树遍历
  • python二叉树类以及其4种遍历方法实例
    目录前言实例代码:相关阅读内容:总结前言 之前学习过binarytree第三方库,了解了它定义的各种基本用法。 昨天在问答频道中做题时碰到一个关于二叉树的算法填空题,感觉代码不错非常...
    99+
    2022-11-11
  • Python二叉树的定义及常用遍历算法分析
    本文实例讲述了Python二叉树的定义及常用遍历算法。分享给大家供大家参考,具体如下: 说起二叉树的遍历,大学里讲的是递归算法,大多数人首先想到也是递归算法。但作为一个有理想有追求的程序员。也应该学学非递归...
    99+
    2022-06-04
    遍历 算法 定义
  • Python实现二叉树结构与进行二叉树遍历的方法详解
    二叉树的建立 使用类的形式定义二叉树,可读性更好 class BinaryTree: def __init__(self, root): self.key = root sel...
    99+
    2022-06-04
    二叉树 遍历 详解
  • JavaScritp中二叉树遍历算法的示例分析
    这篇文章主要为大家展示了“JavaScritp中二叉树遍历算法的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“JavaScritp中二叉树遍历算法的示例...
    99+
    2022-10-19
  • C#中怎么实现一个二叉树遍历算法
    这篇文章给大家介绍C#中怎么实现一个二叉树遍历算法,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。C#算法实现了二叉树的定义,怎么构造一颗已知的二叉树,用几种常规的算法(先序,中序,后序,层次)进行C#二叉树遍历。希望能...
    99+
    2023-06-18
  • 利用JS实现二叉树遍历算法实例代码
    目录前言 一、二叉树 1.1、遍历二叉树 1.2、用js表示二叉树 1.3、前序遍历算法 1.4、中序遍历算法 1.5、后序遍历算法 1.6、按层遍历算法 二、算法题 1.1、二叉树...
    99+
    2022-11-12
  • 图解二叉树的三种遍历方式及java实现代码
    二叉树(binary tree)是一颗树,其中每个节点都不能有多于两个的儿子。1.二叉树节点作为图的特殊形式,二叉树的基本组成单元是节点与边;作为数据结构,其基本的组成实体是二叉树节点(binary tree node),而边则对应于节点之...
    99+
    2023-05-31
    java 二叉树 遍历
  • 如何实现数据结构中的二叉树遍历算法
    今天就跟大家聊聊有关如何实现数据结构中的二叉树遍历算法,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。今天咱们来看一种新...
    99+
    2022-10-19
  • 教你如何使用Python实现二叉树结构及三种遍历
    一:代码实现 class TreeNode: """节点类""" def __init__(self, mid, left=None, right=None): ...
    99+
    2022-11-12
  • Java完全二叉树的创建与四种遍历方法分析
    本文实例讲述了Java完全二叉树的创建与四种遍历方法。分享给大家供大家参考,具体如下:有如下的一颗完全二叉树:先序遍历结果应该为:1  2  4  5  3  6  7中序遍历结果...
    99+
    2023-05-30
    java 二叉树 ava
  • 二叉树递归迭代及morris层序前中后序遍历详解
    目录分析二叉树的前序,中序,后序的遍历步骤1.层序遍历方法一:广度优先搜索方法二:递归2.前序遍历3.中序遍历4.后序遍历递归解法前序遍历--递归中序遍历--递归后序遍历--递归迭代...
    99+
    2022-11-12
  • 剑指Offer之Java算法习题精讲二叉树的构造和遍历
    题目一 二叉树题——最大二叉树 根据给定的数组来构建最大二叉树 具体题目如下  解法 class Solution { public T...
    99+
    2022-11-13
  • php二叉树的遍历以及进行逻辑操作的方法介绍
    本篇内容主要讲解“php二叉树的遍历以及进行逻辑操作的方法介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“php二叉树的遍历以及进行逻辑操作的方法介绍”吧!首先,我们还是要说明一下,我们学习的...
    99+
    2023-06-20
  • C语言进阶二叉树的基础与销毁及层序遍历详解
    单值二叉树 难度简单 如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。 只有给定的树是单值二叉树时,才返回true;否则返回false。 示例 1: 输入:[1,1,...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作