NodeJS:树的序列化

本文也在我的博客edwardesire.com上,欢迎品尝。

接着上周的工作,我们把上周反序列得到的dtree对象输出到JSON,再将其序列化后存入MongoDB。


    1. 存入文档 
      先将上次得到的决策树对象整个保存到JSON文件中,这个需要使用Node内建模块fs的.writeFile()方法,需要记得的一点是,JSON对象需要先使用stringify将其转换为字符串再存入到文件,不然存在文件中的数据就是[object Object]这种JS的对象。

      fs.writeFile(__dirname + ‘/../testjson/trees.json‘, JSON.stringify(dtrees), function (err) {
          if (err) throw err;
          console.log("It‘s writed.");
      });
      
    2. 序列化 
      树结构的序列化参照了python实现二叉树的序列化这篇文章的方法:使用先序来遍历树的节点,将其存入数组。

      首先是解开树结构将节点存入数组当中。

      /**
       * 递归,先序优先历遍每个节点,将节点的子节点存入数组
       * @function serialize
       * @param {Object Node} node 树结构的节点集,递归时为存入node_array的元素(节点)
       *         {Array} node_array 数组结构的节点集
       * @return {Object Node} node 包含树结构的节点,每次递归,节点的children数组元素(节点)少一
       *          {Array} node_array 数组结构的节点集,每次递归,该数组元素(节点)添一
       */
      var serialize = function (node, node_array) {
          while (node.children.length) {
              node_array = serialize(node.children [0], node_array).node_array;
              node.children.splice(0, 1); //.splice(i, 1) 删除node.children[]中index i的元素
              //需要注意 当子节点children数组为空,此步无效
          }
          node_array.push(node); //.push()到node_array
          return ({node: node, node_array: node_array});
      };
      

      每次递归从节点的第一个子节点开始递归,递归回调时删除这个子节点。当跳出循环时,当前节点就是一个没有子节点的单独的节点,这样就可以妥妥地将单个节点存入数组当中,最后将修改后的结果返回给调用处。

      /**
       * 调用递归方法.serialize(),将dtree的树结构节点序列化为数组
       * @function dtreeToArray
       * @param {Object Node} nodes 树结构的节点dtree文档中的node_array节点
       * @return {Array} node_array 升序节点数组
       */
      var dtreeToArray = function (nodes) {
          var node_array = [];
          node_array = serialize(nodes, node_array).node_array;
          node_array.sort(function (a, b) {
              return a.node_id - b.node_id
          });
          //console.log(node_array);
          return node_array;
      };
      

      当序列化结束后,将返回的结果整理排序再返回给上一层的路由控制函数。

    3. 存入数据库 
      最后就是将结果更新到数据库,使用方法.update(),它的第一个参数是条件(等同于关系型中的where),第二个就是需要更新的内容,最后回调函数给出后续操作。
      Dtree.update({"_id": dtreeJsonData._id}, {"node_array": nodes, "config.last_saved_time": Date.now()}, function(err){
              if(err){
                  res.send({‘success‘:false,‘err‘:err});
              }else{
                  //res.send({‘success‘:true});
                  //console.log("dtree created and saved: " + dtree);
                  res.redirect(‘/‘);
              }
      });
      
    4. 总结 
      这样,项目后端比较重要的数据库操作工作就完成了,当然这还需要真实数据来检测。将整个文档读取操作是否足够好和安全,数据库中的参数项是否需要过滤掉,在更新数据库时v值也没有响应的变化,这些问题也需要好好考虑解决。

时间: 2024-10-27 12:30:15

NodeJS:树的序列化的相关文章

数组无限分类树模型序列化

<?php $array = array( array('id'=>'1', 'name'=>'电子产品', 'parent_id'=>0), array('id'=>'2', 'name'=>'电脑', 'parent_id'=>1), array('id'=>'3', 'name'=>'笔记本', 'parent_id'=>2), array('id'=>'4', 'name'=>'台式电脑', 'parent_id'=>2

对于树的序列化,用了stream,很好

https://leetcode.com/problems/serialize-and-deserialize-binary-tree/?tab=Description 下面这个解法里面的C++部分很好: https://discuss.leetcode.com/topic/28041/recursive-preorder-python-and-c-o-n

树的序列化

1. BST 只保存preorder或者postorder就够了,递归有O(n^2)和O(n)算法.非递归有利用栈的O(n)算法. 2. Complete binary tree level traversal就行了. 3. Full binary tree 用一个bit来保存该结点是internal node还是leaf node. 4. General Binary Tree 用NULL来占位.(这个可以是很小位),如果每个结点很大的话,这种方法相比起直接同时存preorder和inorde

树常见的算法操作

树是数据结构中很重要的一部分,也是各大公司面试常考部分. 继树的各种遍历算法之后,今天又整理一下树的常见算法操作. 本文包括: 1.求节点的最近公共祖先 2.树的序列化与反序列化 3.已知先序遍历和中序遍历构造二叉树 4.已知中序遍历和后序遍历构造二叉树 1.求节点最近的公共祖先 此题不同的要求有不同的解法 如果已知树中的每一个结点有指向父节点的指针: 思路:从给定节点遍历到根节点,当父节点相等时返回. 解法1 private ArrayList<TreeNode> getPath2Root(

[LeetCode]652. Find Duplicate Subtrees找到重复树

核心思想是:序列化树 序列化后,用String可以唯一的代表一棵树,其实就是前序遍历改造一下(空节点用符号表示): 一边序列化,一边用哈希表记录有没有重复的,如果有就添加,注意不能重复添加. 重点就是序列化树,序列化得到的String可以唯一的代表一棵树,这个思想很多题都用到了 并不是只是前序遍历就能唯一表示一棵树,加上结构信息就可以了. Map<String,TreeNode> map = new HashMap<>(); List<TreeNode> res = n

数据结构算法 (树 的基本算法)

一.树的序列化 和反序列化 1) 将二叉树进行序列化  和反序列化; 使用的是前序. 1 package com.tree; 2 3 import java.util.LinkedList; 4 import java.util.Queue; 5 6 // 将一个两叉树 序列化成 字符串 ; 7 // 和将一字符串 反序列为一个树. 8 public class TreeNode_Serialization { 9 public static void main(String[] args) {

Leetcode 100. 相同的树(待整理)

1.题目描述 给定两个二叉树,编写一个函数来检验它们是否相同. 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的. 示例 1: 输入: 1 1 / \ / 2 3 2 3 [1,2,3], [1,2,3] 输出: true 示例 2: 输入: 1 1 / 2 2 [1,2], [1,null,2] 输出: false 示例 3: 输入: 1 1 / \ / 2 1 1 2 [1,2,1], [1,1,2] 输出: false 2.解法一:递归 3.解法二:非递归 4.问题转化:树

[总结]树

树作为一种基本的数据结构,也是算法题常考的题型.基本的如树的遍历,树的高度,树的变种数据结构等. 树的遍历 树的遍历有四种:前序,中序,后序,层次.都需要掌握其递归与非递归方式. [leetcode]94.Binary Tree Inorder Traversal 中序遍历 # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = Non

Antlr v4入门教程和实例

1 重逢ANTLR 最早知道ANTLR是当年学习Apache Derby数据库源码时,在看到SQL解析那一层时,第一次看到编译原理在实际项目中的应用,惊叹之余也只能望而却步.之前也根据网上一些资料尝试了一下,看介绍说ANTLR v4更加易用了,于是又好奇地试用一下.以下入门介绍主要参考ANTLR作者写的<The Definitive ANTLR 4 Reference>. 1.1 ANTLR全景 当我们实现一种语言时,我们需要构建读取句子(sentence)的应用,并对输入中的元素做出反应.如