顺序存储二叉树 线索化二叉树

顺序存储二叉树 线索化二叉树

顺序存储二叉树

基本概念:

从数据存储来看,数组存储方式和树的存储方式可以相互转换,即数组可以转换成树,树也可以转换成数组

在这里插入图片描述

要求:

  • 右图的二叉树的结点,要求以数组的方式来存放 arr : [1, 2, 3, 4, 5, 6, 7]
  • 要求在遍历数组 arr 时,仍然可以以前序遍历,中序遍历和后序遍历的方式完成结点的遍历

顺序存储二叉树的特点:

  • 顺序二叉树通常只考虑完全二叉树
  • arr[n] 的左子节点为 arr[2*n + 1]
  • arr[n] 的右子节点为 arr[2*n + 2]
  • arr[n] 的父节点为 arr[ (n-1) /2 ]
  • n : 表示二叉树中的第n个元素,也就是数组索引

说明:八大排序算法中的堆排序,就会使用到顺序存储二叉树

代码实现:

需求: 给你一个数组 {1,2,3,4,5,6,7},要求以二叉树前序,中序 后续 三种方式进行遍历。

package com.atguigu.tree;

/**
 * @ClassName ArrBinaryTreeDemo
 * @Author Jeri
 * @Date 2022-02-22 21:38
 * @Description 顺序存储二叉树
 */


//编写 ArrBinaryTree 实现顺序存储二叉树遍历
class ArrBinaryTree{
    private int[] arr;//存储数据的数组

    public ArrBinaryTree(int[] arr) {
        this.arr = arr;
    }

    //编写顺序二叉树前序遍历
    public void preOrder(int index){
        //如果数组为空 或者 arr.length == 0 无法遍历
        if(arr == null || arr.length == 0){
            System.out.println("数组为空 无法完成遍历");
            return;
        }

        //输出当前元素
        System.out.printf(arr[index] + " ");
        //向左递归
        if((2*index + 1) < arr.length){
            preOrder(2*index + 1);
        }

        //向右递归
        if((2*index + 2) < arr.length){
            preOrder(2*index + 2);
        }
    }

    //实现重载方法 默认前序遍历从0开始
    public void preOrder(){
        this.preOrder(0);
    }

    //编写顺序二叉树中序遍历
    public void infixOrder(int index){
        //如果数组为空 或者 arr.length == 0 无法遍历
        if(arr == null || arr.length == 0){
            System.out.println("数组为空 无法完成遍历");
            return;
        }

        //向左递归
        if((2*index + 1) < arr.length){
            infixOrder(2*index + 1);
        }

        //输出当前元素
        System.out.printf(arr[index] + " ");

        //向右递归
        if((2*index + 2) < arr.length){
            infixOrder(2*index + 2);
        }
    }

    //实现重载方法 默认前序遍历从0开始
    public void infixOrder(){
        this.infixOrder(0);
    }

    //编写顺序二叉树后序遍历
    public void postOrder(int index){
        //如果数组为空 或者 arr.length == 0 无法遍历
        if(arr == null || arr.length == 0){
            System.out.println("数组为空 无法完成遍历");
            return;
        }
        //向左递归
        if((2*index + 1) < arr.length){
            postOrder(2*index + 1);
        }

        //向右递归
        if((2*index + 2) < arr.length){
            postOrder(2*index + 2);
        }

        //输出当前元素
        System.out.printf(arr[index] + " ");
    }

    //实现重载方法 默认前序遍历从0开始
    public void postOrder(){
        this.postOrder(0);
    }


}
public class ArrBinaryTreeDemo {
    public static void main(String[] args) {
        int[] array = new int[]{1, 2, 3, 4, 5, 6, 7};
        //创建 ArrBinaryTree 对象
        ArrBinaryTree abt = new ArrBinaryTree(array);

		System.out.println("原始数组;------");
        System.out.println(Arrays.toString(array));
        System.out.println();
 
        System.out.println("前序遍历结果:------");
        abt.preOrder();
        System.out.println();

        System.out.println("中序遍历结果:------");
        abt.infixOrder();
        System.out.println();

        System.out.println("后序遍历结果:------");
        abt.postOrder();
        System.out.println();
    }
}

原始数组;------
[1, 2, 3, 4, 5, 6, 7]

前序遍历结果:------
1 2 4 5 3 6 7 
中序遍历结果:------
4 2 5 1 6 3 7 
后序遍历结果:------
4 5 2 6 7 3 1 

线索化二叉树

提出问题:

将数列 {1, 3, 6, 8, 10, 14 } 构建成一颗二叉树

在这里插入图片描述

问题分析:

  • 当我们对上面的二叉树进行中序遍历时,数列为 {8, 3, 10, 1, 14,6 }
  • 但是 6, 8, 10, 14 这几个节点的 左右指针,并没有完全的利用上
  • 如果我们希望充分的利用 各个节点的左右指针, 让各个节点可以指向自己的前后节点
  • 解决方案:线索二叉树

基本介绍:

  • n 个结点的二叉链表中含有 n+1 (公式 2n-(n-1)=n+1) 个空指针域。利用二叉链表中的空指针域,存放指向该结点在某种遍历次序下的前驱和后继结点的指针(这种附加的指针称为"线索")
  • 这种加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树(Threaded BinaryTree)。根据线索性质的不同,线索二叉树可分为前序线索二叉树、中序线索二叉树和后序线索二叉树三种
  • 一个结点的前一个结点,称为前驱结点
  • 一个结点的后一个结点,称为后继结点

中序线索化二叉树的构建

应用案例说明:将下面的二叉树,进行中序线索二叉树。中序遍历的数列为 {8, 3, 10, 1, 14, 6}

在这里插入图片描述

说明: 当线索化二叉树后,Node 节点的 属性 left 和 right ,有如下情况

  • left 指向的是左子树,也可能是指向的前驱节点. 比如 1 节点 left 指向的左子树, 而 10 节点的 left 指向的就是前驱节点
  • right 指向的是右子树,也可能是指向后继节点,比如 1 节点 right 指向的是右子树,而 10 节点的 right 指向的是后继节点.
package com.atguigu.tree;

/**
 * @ClassName ThreadedBinaryTreeDemo
 * @Author Jeri
 * @Date 2022-02-23 10:25
 * @Description 线索二叉树 分为前序 中序 后序
 */


//创建节点类
class Node{
    private int no;
    private Node left;//默认为 null
    private Node right;//默认为 null

    //取值说明:leftType/rightType  0:左右子树  1:前驱 后继节点
    private int leftType;
    private int rightType;

    public Node(int no) {
        this.no = no;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public Node getLeft() {
        return left;
    }

    public void setLeft(Node left) {
        this.left = left;
    }

    public Node getRight() {
        return right;
    }

    public void setRight(Node right) {
        this.right = right;
    }

    public int getLeftType() {
        return leftType;
    }

    public void setLeftType(int leftType) {
        this.leftType = leftType;
    }

    public int getRightType() {
        return rightType;
    }

    public void setRightType(int rightType) {
        this.rightType = rightType;
    }

    @Override
    public String toString() {
        return "Node{" +
                "no=" + no +
                '}';
    }
}

//定义 ThreadedBinaryTree 实现 线索化二叉树
class ThreadedBinaryTree{
    private Node root;

    public void setRoot(Node node){
        this.root = node;
    }

    public Node getRoot() {
        return root;
    }

    //实现线索化 创建临时节点 指向当前节点的前驱节点
    private Node pre = null;


    /*
     * @Description 中序线索化二叉树
     * 中序遍历的数列为 {8, 3, 10, 1, 14, 6}
     * 思路:先找到 node = 8 pre = null,然后按照顺序逐次后移
     * @Date 2022/2/23 10:36
     * @param node 开始节点(根节点)
     */
    public void infixThreadedNodes(Node node){

        //如果 node ==null 不能线索化
        if(node == null) { return ;}

        //线索化左子树
        //使用递归找到 node = 8 这个节点 顺次后移处理
        infixThreadedNodes(node.getLeft());

        //线索化当前节点
        //1.处理前驱节点
        if(node.getLeft() == null){
            //当前节点 左指针为空 使其指向 前驱节点
            node.setLeft(pre);
            //修改其左指针的类型
            node.setLeftType(1);
        }
        //2.处理后继节点
        //当前 node 节点不知道其后继节点
        //但是根据双指针移动策略 在下一次移动中 pre -> node node->node.next
        //所以我们在下一轮 来处理当前节点的后继
        if(pre != null && pre.getRight() == null){
            //设置上一轮节点的后继节点
            pre.setRight(node);
            //修改上一轮节点的指针类型
            pre.setRightType(1);
        }

        //处理节点后 使得 pre 后移
        pre = node;

        //node的移动是根据递归进行 无需手动操作

        //线索化右子树
        infixThreadedNodes(node.getRight());
    }

}

public class ThreadedBinaryTreeDemo {
    public static void main(String[] args) {
        //创建节点对象
        Node node1 = new Node(1);
        Node node2 = new Node(3);
        Node node3 = new Node(6);
        Node node4 = new Node(8);
        Node node5 = new Node(10);
        Node node6 = new Node(14);

        //手动创建二叉树
        node1.setLeft(node2);
        node1.setRight(node3);
        node2.setLeft(node4);
        node2.setRight(node5);
        node3.setLeft(node6);

        //创建线索树对象
        ThreadedBinaryTree tbt = new ThreadedBinaryTree();
        tbt.setRoot(node1);

        //进行中序线索化
        tbt.infixThreadedNodes(tbt.getRoot());

        //测试结果
        System.out.println("测试中序线索化二叉树:------");


        Node leftNode = node5.getLeft();
        Node rightNode = node5.getRight();
        System.out.println("10号结点的前驱结点是 = " + leftNode);// 3
        System.out.println("10号结点的后继结点是 = " + rightNode);// 1
    }
}
测试中序线索化二叉树:------
10号结点的前驱结点是 = Node{no=3}
10号结点的后继结点是 = Node{no=1}

中序线索化二叉树的中序遍历

说明:对前面的中序线索化的二叉树, 进行遍历

分析:因为线索化后,各个结点指向有变化,因此原来的遍历方式不能使用,这时需要使用新的方式遍历线索化二叉树,各个节点可以通过线型方式遍历,因此无需使用递归方式,这样也提高了遍历的效率。 遍历的次序应当和中序遍历保持一致

在这里插入图片描述

思路分析: 顺着 左线型0 找到节点 8 ,输出节点 8 ,然后顺着 右线性 进行进行查找 右线性 = 1,存在后继节点,node = node.getRight() 继续判断 右线型;否则 右线性 != 1,node 后移 node.getRight(),从头继续

ThreadedBinaryTree 类中增加方法

/*
     * @Description 中序线索化二叉树的中序遍历 
     * @Date 2022/2/23 11:34
     */
    public void infixThreadedNodeList(){
        //定义一个临时变量 存储便利的节点 从 root 开始
        Node node = root;

        while (node != null){
            //顺着左线型 找到 节点8
            while (node.getLeftType() == 0){
                node = node.getLeft();
            }
            //退出循环时 node -> 8

            //打印当前节点
            System.out.println(node);

            //顺着右线型进行查找
            //1. 右线型 == 1 node -> node.next 输出
            //2. 右线型 == 0 node -> node.getRight()
            while (node.getRightType() == 1){
                //当前节点存在后继节点 node 后移
                node = node.getRight();
                System.out.println(node);
            }

            //否则
            node = node.getRight();
        }
    }

ThreadedBinaryTreeDemo类中增加测试代码

        System.out.println("测试中序线索化二叉树的中序遍历:------");
        tbt.infixThreadedNodeList();
测试中序线索化二叉树的中序遍历:------
Node{no=8}
Node{no=3}
Node{no=10}
Node{no=1}
Node{no=14}
Node{no=6}

前序线索化二叉树的构建

应用案例说明:将下面的二叉树,进行前序线索二叉树。前序遍历的数列为 {1,3,8,10,6,14}

在这里插入图片描述

说明: 当线索化二叉树后,Node 节点的 属性 left 和 right ,有如下情况

  • left 指向的是左子树,也可能是指向的前驱节点. 比如 1 节点 left 指向的左子树, 而 10 节点的 left 指向的就是前驱节点
  • right 指向的是右子树,也可能是指向后继节点,比如 1 节点 right 指向的是右子树,而 10 节点的 right 指向的是后继节点.

ThreadedBinaryTree 类中 增加方法

/*
     * @Description 前序线索化二叉树的构建
     * 前序遍历的数列为 {1,3,8,10,6,14}
     * 思路:先找到 node = 1 pre = null,然后按照顺序逐次后移
     * @Date 2022/2/23 15:53
     */
    public void preThreadedNodes(Node node){
        //如果 node ==null 不能线索化
        if(node == null) { return ;}

        //处理当前节点
        //1.处理前驱节点
        if(node.getLeft() == null){
            //当前节点 左指针为空 使其指向 前驱节点
            node.setLeft(pre);
            //修改其左指针的类型
            node.setLeftType(1);
        }

        //2.处理后继节点
        //当前 node 节点不知道其后继节点
        //但是根据双指针移动策略 在下一次移动中 pre -> node node->node.next
        //所以我们在下一轮 来处理当前节点的后继
        if(pre != null && pre.getRight() == null){
            //设置上一轮节点的后继节点
            pre.setRight(node);
            //修改上一轮节点的指针类型
            pre.setRightType(1);
        }

        //处理节点后 使得 pre 后移
        pre = node;

        //node的移动是根据递归进行 无需手动操作

        //排除 node.getLeft() = pre  的情况 避免无限循环
        if(node.getLeftType() == 0){
            //线索化左子树
            preThreadedNodes(node.getLeft());
        }

        //线索化右子树
        if(node.getRightType() == 0) {
            preThreadedNodes(node.getRight());
        }

    }

ThreadedBinaryTreeDemo 类中增加测试代码

        System.out.println();

        //进行前序线索化
        tbt.preThreadedNodes(tbt.getRoot());
        Node leftNode = node5.getLeft();
        Node rightNode = node5.getRight();
        System.out.println("10号结点的前驱结点是 = " + leftNode);// 8
        System.out.println("10号结点的后继结点是 = " + rightNode);// 6

        System.out.println("前序线索化结束");
10号结点的前驱结点是 = Node{no=8}
10号结点的后继结点是 = Node{no=6}
前序线索化结束

debug下发现 节点 14 的右指针 指向 null 线型为0 与计划不是很符合

前序线索化二叉树的前序遍历

ThreadedBinaryTree类中增加方法

/*
     * @Description 前序线索化二叉树的前序遍历
     * 前序遍历的数列为 {1,3,8,10,6,14}
     * 思路:先找到 node = 1 pre = null,然后按照顺序逐次后移
     * @Date 2022/2/23 15:53
     */
    public void preThreadedNodesList(){
        //定义临时变量 存储遍历的节点 从root开始
        Node node = root;

        while (node != null){

            //打印当前结点
            System.out.println(node);

            //找到最左边的节点
            while (node.getLeftType()==0){
                node=node.getLeft();
                System.out.println(node);
            }

            if (node.getRightType()==1){
                node=node.getRight();
            }else if (node.getRight()==null){
                //线索化前序遍历的最后一个结点的right一定为null,所以遍历完毕 退出循环
                break;
            }
        }

    }

ThreadedBinaryTreeDemo类中增加测试方法

        System.out.println();
        System.out.println("测试前序线索化二叉树的前序遍历:------");
        tbt.preThreadedNodesList();
测试前序线索化二叉树的前序遍历:------
Node{no=1}
Node{no=3}
Node{no=8}
Node{no=10}
Node{no=6}
Node{no=14}

后序线索化二叉树的构建

应用案例说明:将下面的二叉树,进行后序线索二叉树。后序遍历的数列为 {8,10,3,14,6,1}

在这里插入图片描述

说明: 当线索化二叉树后,Node 节点的 属性 left 和 right ,有如下情况

  • left 指向的是左子树,也可能是指向的前驱节点. 比如 1 节点 left 指向的左子树, 而 10 节点的 left 指向的就是前驱节点
  • right 指向的是右子树,也可能是指向后继节点,比如 1 节点 right 指向的是右子树,而 10 节点的 right 指向的是后继节点.

ThreadedBinaryTree 类中 增加方法

/*
     * @Description 后序线索化二叉树的构建
     * 后序遍历的数列为 {8, 3, 10, 1, 14, 6}
     * 思路:先找到 node = 8 pre = null,然后按照顺序逐次后移
     * @Date 2022/2/23 10:36
     * @param node 开始节点(根节点)
     */
    public void postThreadedNodes(Node node){
        //如果 node 为空 不能进行线索化
        if(node == null) { return; }

        //先线索化左子树
        postThreadedNodes(node.getLeft());

        //在线索化右子树
        postThreadedNodes(node.getRight());

        //当前节点
        //1.处理前驱节点
        if(node.getLeft() == null){
            //当前节点 左指针为空 使其指向 前驱节点
            node.setLeft(pre);
            //修改其左指针的类型
            node.setLeftType(1);
        }

        //2.处理后继节点
        //当前 node 节点不知道其后继节点
        //但是根据双指针移动策略 在下一次移动中 pre -> node node->node.next
        //所以我们在下一轮 来处理当前节点的后继
        if(pre != null && pre.getRight() == null){
            //设置上一轮节点的后继节点
            pre.setRight(node);
            //修改上一轮节点的指针类型
            pre.setRightType(1);
        }

        //处理节点后 使得 pre 后移
        pre = node;

        //node的移动是根据递归进行 无需手动操作
    }

ThreadedBinaryTreeDemo类中增加测试代码

        //进行后序线索化
        tbt.postThreadedNodes(tbt.getRoot());
        Node leftNode = node5.getLeft();
        Node rightNode = node5.getRight();
        System.out.println("10号结点的前驱结点是 = " + leftNode);// 8
        System.out.println("10号结点的后继结点是 = " + rightNode);// 6

        System.out.println("后序线索化结束");
10号结点的前驱结点是 = Node{no=8}
10号结点的后继结点是 = Node{no=3}
后序线索化结束

后序线索化二叉树的后序遍历

注:参考其他人 自己没有写出来

参考文献:后序线索化二叉树(Java版)

ThreadedBinaryTree类中增加方法

Node类中增加属性

    private Node parent;//表示父节点 后续线索化要用
	public Node getParent() {
        return parent;
    }

    public void setParent(Node parent) {
        this.parent = parent;
    }
/*
     * @Description 后序线索化二叉树
     * 思路:后序遍历开始节点是最左节点
     * @Date 2022/2/23 19:13
     */
    public void postThreadedNodesList(){

        //1.找到后序遍历最开始的节点
        Node node = root;
        while (node != null && node.getLeftType() == 0){
            node = node.getLeft();
        }

        //定义父节点
        Node preNode = null;

        while (node != null){
            //右节点是线索
            if(node.getRightType() == 1){
                System.out.println(node);
                preNode = node;
                node = node.getRight();
            }else{
                //如果上个处理的节点是当前节点的右节点
                if(node.getRight() == preNode){
                    System.out.println(node);
                    if(node == root){
                        break;
                    }

                    preNode = node;
                    node = node.getParent();
                }else{
                    //如果从左节点的进入  则找到有子树的最左节点

                    //排除该节点为 root 节点且右子树为空的情况
                    if(node == root && node.getRight() == null){
                        System.out.println(node);
                        return;
                    }else{
                        node = node.getRight();
                        while (node != null && node.getLeftType() == 0){
                            node = node.getLeft();
                        }
                    }
                }
            }
        }
    }

ThreadedBinaryTreeDemo类中增加测试代码

		node2.setParent(node1);
        node3.setParent(node2);
        node4.setParent(node2);
        node5.setParent(node2);
        node6.setParent(node3);
		//进行后序线索化
        tbt.postThreadedNodes(tbt.getRoot());
        System.out.println();
        System.out.println("测试后序线索化二叉树的后序遍历:------");
        tbt.postThreadedNodesList();
测试后序线索化二叉树的后序遍历:------
Node{no=8}
Node{no=10}
Node{no=3}
Node{no=14}
Node{no=6}
Node{no=1}

小结遍历

参考文献:后序线索化二叉树(Java版)

  • 前序线索化二叉树遍历:先沿着左子树处理,找到子树的最左子节点,然后处理right指针指向,以此类推,直到节点的right指针为空,说明是最后一个,遍历完成。
  • 中序线索化二叉树遍历:左根右,因此第一个节点一定是最左子节点,先找到最左子节点,依次沿着right指针指向进行处理(无论是指向子节点还是指向后继节点),直到节点的right指针为空,说明是最后一个,遍历完成。
  • 后序遍历线索化二叉树最为复杂,通用的二叉树数节点存储结构不能够满足后序线索化,因此我们扩展了节点的数据结构,增加了父节点的指针。后序的遍历顺序是:左右根,先找到最左子节点,沿着right后继指针处理,当right不是后继指针时,并且上一个处理节点是当前节点的右节点,则处理当前节点的右子树,遍历终止条件是:当前节点是root节点,并且上一个处理的节点是root的right节点

参考文献

尚硅谷Java数据结构与java算法

原文地址:https://blog.csdn.net/dizhi_buyu/article/details/123077977

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


这篇文章主要介绍“基于nodejs的ssh2怎么实现自动化部署”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“基于nodejs...
本文小编为大家详细介绍“nodejs怎么实现目录不存在自动创建”,内容详细,步骤清晰,细节处理妥当,希望这篇“nodejs怎么实现目录不存在自动创建”文章能帮助大...
这篇“如何把nodejs数据传到前端”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这...
本文小编为大家详细介绍“nodejs如何实现定时删除文件”,内容详细,步骤清晰,细节处理妥当,希望这篇“nodejs如何实现定时删除文件”文章能帮助大家解决疑惑...
这篇文章主要讲解了“nodejs安装模块卡住不动怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来...
今天小编给大家分享一下如何检测nodejs有没有安装成功的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文...
本篇内容主要讲解“怎么安装Node.js的旧版本”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎...
这篇“node中的Express框架怎么安装使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家...
这篇文章主要介绍“nodejs如何实现搜索引擎”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“nodejs如何实现搜索引擎...
这篇文章主要介绍“nodejs中间层如何设置”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“nodejs中间层如何设置”文...
这篇文章主要介绍“nodejs多线程怎么实现”,在日常操作中,相信很多人在nodejs多线程怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法...
这篇文章主要讲解了“nodejs怎么分布式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“nodejs怎么分布式”...
本篇内容介绍了“nodejs字符串怎么转换为数组”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情...
这篇文章主要介绍了nodejs如何运行在php服务器的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇nodejs如何运行在php服务器文章都...
本篇内容主要讲解“nodejs单线程如何处理事件”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“nodejs单线程如何...
这篇文章主要介绍“nodejs怎么安装ws模块”,在日常操作中,相信很多人在nodejs怎么安装ws模块问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法...
本篇内容介绍了“怎么打包nodejs代码”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!
本文小编为大家详细介绍“nodejs接收到的汉字乱码怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“nodejs接收到的汉字乱码怎么解决”文章能帮助大家解...
这篇“nodejs怎么同步删除文件”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇...
今天小编给大家分享一下nodejs怎么设置淘宝镜像的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希