接下来让我们一起来探讨js数据结构中的树。这里的树类比现实生活中的树,有树干,树枝,在程序中树是一种数据结构,对于存储需要快速查找的数据非有用,它是一种分层数据的抽象模型。一个树结构包含一系列存在父子关系的节点。每个节点都有一个父节点以及零个或多个子节点。

 前端: JavaScript 中的二叉树算法完成(JavaScript 二叉树) 数据结构 前端 第1张

接下来让咱们一起来讨论js数据结构中的树。这儿的树类比现实生活中的树,有树干,树枝,在程序中树是一种数据结构,关于存储需求快速查找的数据非有用,它是一种分层数据的笼统模型。一个树结构包括一系列存在父子联系的节点。每个节点都有一个父节点以及零个或多个子节点。如下所认为一个树结构:)

 前端: JavaScript 中的二叉树算法完成(JavaScript 二叉树) 数据结构 前端 第2张
  • 和树相关的概念:1.子树:由节点和他的子孙构成,如上图标明处。2.深度:节点的深度取决于它祖节点的数量,比方节点5有2个祖节点,他的深度为2。3.高度:树的高度取决于一切节点深度的最大值。

二叉树和二叉查找树介绍

二叉树中的节点最多只能有2个子节点,一个是左边子节点,一个是右侧子节点,这样界说的优点是有利于咱们写出更高效的刺进,查找,删去节点的算法。二叉查找树是二叉树的一种,可是它只允许你在左边子节点存储比父节点小的值,但在右侧节点存储比父节点大的值。接下来咱们将依照这个思路去完成一个二叉查找树。

 前端: JavaScript 中的二叉树算法完成(JavaScript 二叉树) 数据结构 前端 第3张

1. 创立BinarySearchTree类

这儿咱们将运用结构函数去创立一个类:

  1. functionBinarySearchTree(){
  2. //用于创立节点的类
  3. letNode=function(key){
  4. this.key=key;
  5. this.left=null;
  6. this.right=null;
  7. }
  8. //根节点
  9. letroot=null;
  10. }

咱们将运用和链表相似的指针办法去表明节点之间的联系,假如不了解链表,请看我后序的文章《怎么完成单向链表和双向链表》。

2.刺进一个键

  1. //刺进一个键
  2. this.insert=function(key){
  3. letnewNode=newNode(key);
  4. root===null?(root=newNode):(insertNode(root,newNode))
  5. }

向树中刺进一个新的节点主要有以下三部分:1.创立新节点的Node类实例 --> 2.判别刺进操作是否为根节点,是根节点就将其指向根节点 --> 3.将节点参加非根节点的其他方位。

insertNode的详细完成如下:

  1. functioninsertNode(node,newNode){
  2. if(newNode.key<node.key){
  3. node.left===null?(node.left=newNode):(insertNode(node.left,newNode))
  4. }else{
  5. node.right===null?(node.right=newNode):(insertNode(node.right,newNode))
  6. }
  7. }

这儿咱们用到递归,接下来要完成的search,del等都会很多运用递归,所以说不了解的能够先自行学习了解。咱们创立一个二叉树实例,来刺进一个键:

  1. lettree=newBinarySearchTree();
  2. tree.insert(20);
  3. tree.insert(21);
  4. tree.insert(520);
  5. tree.insert(521);

刺进的结构会依照二叉查找树的规矩去刺进,结构相似于上文的第一个树图。

树的遍历

拜访树的一切节点有三种遍历办法:中序,先序和后序。

  • 中序遍历:以从最小到最大的次序拜访一切节点
  • 先序遍历:以优先于子孙节点的次序拜访每个节点
  • 后序遍历:先拜访节点的子孙节点再拜访节点自身

依据以上的介绍,咱们能够有以下的完成代码。

1 中序排序

  1. this.inOrderTraverse=function(cb){
  2. inOrderTraverseNode(root,cb);
  3. }
  4. //辅佐函数
  5. functioninOrderTraverseNode(node,cb){
  6. if(node!==null){
  7. inOrderTraverseNode(node.left,cb);
  8. cb(node.key);
  9. inOrderTraverseNode(node.right,cb);
  10. }
  11. }

运用中序遍历能够完成对树进行从小到大排序的功用。

2 先序排序

  1. //先序排序---优先于子孙节点的次序拜访每个节点
  2. this.preOrderTraverse=function(cb){
  3. preOrderTraverseNode(root,cb);
  4. }
  5. //先序排序辅佐办法
  6. functionpreOrderTraverseNode(node,cb){
  7. if(node!==null){
  8. cb(node.key);
  9. preOrderTraverseNode(node.left,cb);
  10. preOrderTraverseNode(node.right,cb);
  11. }
  12. }

运用先序排序能够完成结构化输出的功用。

3 后序排序

  1. //后续遍历---先拜访子孙节点,再拜访节点自身
  2. this.postOrderTraverse=function(cb){
  3. postOrderTraverseNode(root,cb);
  4. }
  5. //后续遍历辅佐办法
  6. functionpostOrderTraverseNode(node,cb){
  7. if(node!==null){
  8. postOrderTraverseNode(node.left,cb);
  9. postOrderTraverseNode(node.right,cb);
  10. cb(node.key);
  11. }
  12. }

后序遍历能够用于核算有层级联系的一切元素的巨细。

查找树中的值

在树中有三种常常履行的查找类型:最大值,最小值,特定的值。

1 最小值

最小值经过界说能够知道便是左边树的最底端的节点,详细完成代码如下:

  1. //最小值
  2. this.min=function(){
  3. returnminNode(root)
  4. }
  5. functionminNode(node){
  6. if(node){
  7. while(node&&node.left!==null){
  8. node=node.left;
  9. }
  10. returnnode.key
  11. }
  12. returnnull
  13. }

相似的,完成最大值的办法如下:

  1. //最大值
  2. this.max=function(){
  3. returnmaxNode(root)
  4. }
  5. functionmaxNode(node){
  6. if(node){
  7. while(node&&node.right!==null){
  8. node=node.right;
  9. }
  10. returnnode.key
  11. }
  12. returnnull
  13. }

2.查找一个特定的值

  1. //查找树中某个值
  2. this.search=function(key){
  3. returnsearchNode(root,key)
  4. }
  5. //查找辅佐办法
  6. functionsearchNode(node,key){
  7. if(node===null){
  8. returnfalse
  9. }
  10. if(key<node.key){
  11. returnsearchNode(node.left,key)
  12. }elseif(key>node.key){
  13. returnsearchNode(node.right,key)
  14. }else{
  15. returntrue
  16. }
  17. }

3 移除一个节点

  1. //刺进一个键
  2. this.insert=function(key){
  3. letnewNode=newNode(key);
  4. root===null?(root=newNode):(insertNode(root,newNode))
  5. }
0

删去节点需求考虑的状况比较多,这儿咱们会运用和min相似的完成去写一个发现最小节点的函数,当要删去的节点有两个子节点时,咱们要将当时要删去的节点替换为子节点中最大的一个节点的值,然后将这个子节点删去。

至此,一个二叉查找树现已完成,可是还存在一个问题,假如树的一遍十分深,将会存在必定的功能问题,为了处理这个问题,咱们能够使用AVL树,一种自平衡二叉树,也就是说任何一个节点的左右两边子树的高度之差最多为1。

 前端: JavaScript 中的二叉树算法完成(JavaScript 二叉树) 数据结构 前端 第4张

转载请说明出处
知优网 » 前端: JavaScript 中的二叉树算法完成(JavaScript 二叉树)

发表评论

您需要后才能发表评论