js二叉树实现

1 .简介

二叉树结构

如上图所示:
“8”为root节点(根节点),“3”和“10”分别为“8” 的左子节点(左子树)和右子节点(右子树),
这颗二叉树的高度为4层,
“4”、“6”、“13”没有子节点(左右子树都没),也称为叶子节点
“8”的左子树“3”小于“8”,右子树“10”大于“8”;“3”的左子树“1”小于“3”,右子树“5”大于“3”,形如这种的二叉树称为排序二叉树

2 .代码实现

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>js二叉树</title>
</head>
<body>
  <script>
    // 二叉树构造函数
    function BinaryTree() {
      // 节点的构造函数
      var Node = function(key) {
        this.key = key; // 节点的值
        this.left = null; // 左子树节点
        this.right = null; // 右子树节点
      }

      // 根节点
      var root = null;

      // 插入root的子节点
      var insertNode = function(parentNode, childNode){
        // 左子树构造
        if (childNode.key < parentNode.key) {
          // 为空时赋值,否则继续延伸
          if (parentNode.left === null) {
            parentNode.left = childNode;
          } else {
            insertNode(parentNode.left, childNode);
          }
        } else { // 右子树的构造 childNode.key > parentNode.key
          if (parentNode.right === null) {
            parentNode.right = childNode;
          } else {
            insertNode(parentNode.right, childNode);
          }
        }

      }

      this.getRoot = function() {
        return root;
      }

      // 插入节点的实例方法
      this.insert = function(key) {
        var thisNode = new Node(key);

        // 根节点赋值
        if (root === null) {
          root = thisNode;
        } else {
          // 插入子节点
          insertNode(root, thisNode);
        }
      }
    }

    var nodes = [8, 3, 10, 1, 5, 14, 4, 6, 13];
    var binaryTree = new BinaryTree();
    nodes.forEach( key => {
      binaryTree.insert(key);
    });
    console.log(binaryTree.getRoot());
    
  </script>
</body>
</html>

查看树的结构
输入的二叉树的结构

3 .三种遍历方法(中序、前序、后序)

3.1 中序遍历

解析:从根节点(‘8’)作为入口,查看该节点的左子树,如果有,则进入该子树(‘3’),查看’3’有无左子树,有则进入到’3’的左子树’1’,‘1’没有左子树,则输出该节点的值,为 1。‘1’没有右子树,则返回上一层’3’,输出 3。查看’3’的右子树,有则进入’5’,‘5’有左子树,则进入到’4’,‘4’为叶子节点,所以直接输出 4
返回上一层’5’,并输出 5 。然后进入’5’的右子树’6’,‘6’为叶子节点直接输出 6。然后返回’5’,‘5’已输出继续返回上一层’3’,‘3’也输出了,返回到’8’,然后输出 8 。'8’的右子树同理。
则顺序为1、3、4、5、6、8、10、13、14 为升序

部分代码为:

      // 中序遍历的实例方法
      this.inOrderTraverse = function(node, printLog) {
        if (node !== null) {
          // 优先去找左子树,然后中间节点,最后右子树
          this.inOrderTraverse(node.left, printLog);
          printLog(node.key);
          this.inOrderTraverse(node.right, printLog);
        }
      }
    }

    // 节点数组
    var nodes = [8, 3, 10, 1, 5, 14, 4, 6, 13];
    // 打印方法
    var printLog = key => console.log(key);
    var binaryTree = new BinaryTree();
    nodes.forEach( key => {
      binaryTree.insert(key);
    });
    var root = binaryTree.getRoot();
    console.log(root);
    binaryTree.inOrderTraverse(root, printLog);

3.2 前序遍历

解析:从根节点’8’进入并打印,然后进去左子树’3’并打印,再进入’3’的左子树’1’并打印,‘1’为叶子节点返回到上一层’3’,进入右子树’5’并打印,然后进入’5’的左子树’4’并打印,‘4’为叶子节点返回上一层’5’,进去右子树’6’并打印,然后逐一返回至根节点遍历根节点的右子树…

作用复制二叉树效率高

部分代码为:

// 前序遍历的实例方法
      this.preTraverse = function(node, printLog) {
        if (node !== null) {
          // 优先输出中间节点,然后寻找左子树,最后右子树
          printLog(node.key);
          this.preTraverse(node.left, printLog);
          this.preTraverse(node.right, printLog);
        }
      }
    }

    // 节点数组
    var nodes = [8, 3, 10, 1, 5, 14, 4, 6, 13];
    // 打印方法
    var printLog = key => console.log(key);
    var binaryTree = new BinaryTree();
    nodes.forEach( key => {
      binaryTree.insert(key);
    });
    var root = binaryTree.getRoot();
    console.log(root);
    // 中序遍历
    // binaryTree.inOrderTraverse(root, printLog);

    // 前序遍历
    binaryTree.preTraverse(root, printLog);

输出结果为:8、3、1、5、4、6、10、14、13

3.3 后序遍历

解析:首先寻找左节点最深处的并打印,然后右子树并打印,最后中间节点。

部分代码为:

扫描二维码关注公众号,回复: 6232601 查看本文章
	  // 后序遍历的实例方法
      this.postTraverse = function(node, printLog) {
        if (node !== null) {
          // 优先输出左子树,然后寻找右子树,最后中间节点
          this.postTraverse(node.left, printLog);
          this.postTraverse(node.right, printLog);
          printLog(node.key);
        }
      }
    }

    // 节点数组
    var nodes = [8, 3, 10, 1, 5, 14, 4, 6, 13];
    // 打印方法
    var printLog = key => console.log(key);
    var binaryTree = new BinaryTree();
    nodes.forEach( key => {
      binaryTree.insert(key);
    });
    var root = binaryTree.getRoot();
    console.log(root);
    // 中序遍历
    // binaryTree.inOrderTraverse(root, printLog);

    // 前序遍历
    // binaryTree.preTraverse(root, printLog);
    
    //后序遍历
    binaryTree.postTraverse(root, printLog);

输出结果为:1、4、6、5、3、13、14、10、8

此部分完整代码

4 .查询节点

4.1.查找最小值

解析:从root节点开始寻找左子树,如果没有左子树则表明该节点为最小值。

代码:

	  // 查询最小值
      this.minNode = function(node) {
        if (node !== null) {
          while(node && node.left !== null) {
            node = node.left;
          }
          return node.key;
        }
        return null;
      }

4.2.查找最大值

解析:从root节点开始寻找右子树,如果没有右子树则表明该节点为最大值。

部分代码:

	  // 查询最大值
      this.maxNode = function(node) {
        if (node !== null) {
          while(node && node.right !== null) {
            node = node.right;
          }
          return node.key;
        }
        return null;
      }

4.2.查找指定值

部分代码:

      // 查找指定值
      this.searchNode = function(node, key) {
        if (node === null) {
          return false;
        }
        // 要查找的值小于当前节点的值,用左子树继续查找
        if (key < node.key) {
          return this.searchNode(node.left, key);
        } else if (key > node.key) { // 要查找的值大于当前节点的值,用右子树继续查找
          return this.searchNode(node.right, key);
        } else {
          return true;
        }
      }

此部分完整代码

猜你喜欢

转载自blog.csdn.net/ky1in93/article/details/88115210