二叉樹算法訓(xùn)練

1.二叉樹相關(guān)遍歷 二叉搜索樹(有序:根大于左子樹小于右子樹)相關(guān)遍歷 (迭代和遞歸)

適當(dāng)?shù)木毦毷郑涗浺幌隆?br> System.out.println("中序遍歷結(jié)果 = " + inorderTraversal(treeNode));
System.out.println("前序遍歷結(jié)果 = " + inorderTraversal1(treeNode));
System.out.println("后序遍歷結(jié)果 = " + inorderTraversal2(treeNode));
System.out.println("層序遍歷結(jié)果 = " + levelOrder(treeNode));
System.out.println("二叉樹的最大深度 = " + maxDepthInIteration(treeNode));
System.out.println("對稱二叉樹 = " + isSymmetric(treeNode));
System.out.println("二叉樹路徑總合 = " + hasPathSum(treeNode, 7));
System.out.println("從中序與后序遍歷序列構(gòu)造二叉樹 中序顯示= " + inorderTraversal(buildTree(inorder, postorder)));
System.out.println("二叉樹的最近公共祖先 = " + lowestCommonAncestor(treeNode, new TreeNode(2),new TreeNode(3)));
System.out.println("二叉樹的序列化與反序列化 = " + serialize(treeNode));
System.out.println("二叉樹的反序列化 中序顯示= " + inorderTraversal(deserialize("1,2,#,#,3,#,#,")));
System.out.println("是否是二叉搜索樹 = " + isValidBST(treeNode));
System.out.println("searchBST 二叉樹搜索樹搜索某個節(jié)點= " + searchBST(treeNode,3));
System.out.println("二叉樹搜索樹插入某個節(jié)點 中序顯示= " + inorderTraversal(insertIntoBST(treeNode,4)));

package com.test.algorithm;

import javafx.util.Pair;

import java.util.*;

/**
 * @author rs
 * @version 1.0
 * @date 2020/2/18 0018 10:33
 * 二叉樹中序遍歷 迭代
 *    1
 *  2  3 左右根
 */
public class OrderTraversalInBinaryTree {


    /*************************************************中序遍歷**************************************************/
    /**
     * 中序遍歷 迭代
     * @param root
     * @return
     */
    public static  List<Integer> inorderTraversal(TreeNode root) {

        List<Integer> list = new ArrayList<>();
        if(root == null) {
            return list;
        }
        Stack<TreeNode> stack = new Stack<>(); // 棧先進后出
        TreeNode cur = root;
        while(cur != null || !stack.isEmpty()) { // 8.curr = null, statck.size = 1  12.cur != null 18.cur = null, stack.size = 0
            while(cur != null) {
                stack.push(cur); // 進棧 1.將整個cur推進stack里面 3.將左節(jié)點推進stack,此時stack.size = 2  13.將3,null,null推進棧
                cur = cur.left;  // 2.將cur的left賦值給cur,cur就成為了左節(jié)點 4.此時的cur的左節(jié)點為null   14.cur = null
            }
            cur = stack.pop(); // 出棧 5.因為先進后出,所以cur=root的左節(jié)點(這里需要有空間想象) 9.將之前的root彈出來  15.cur = 3
            list.add(cur.val); // 6.此時val = 2,因為在第4步整個cur的左節(jié)點都為null,如果它有右節(jié)點也是排在2后面的  10. 添加根節(jié)點1 16. 添加根節(jié)點3
            cur = cur.right; // 7.cur = null 11. cur = 3,null,null 17.cur = null
        }
        return list;
    }

    /**
     * 中序遍歷 遞歸
     * @param root
     * @return
     */
    List<Integer> inorderTraversalForTterationList = new ArrayList<>();
    public List<Integer> inorderTraversalForTteration(TreeNode root) {

        if (root != null) {
            inorderTraversalForTteration(root.left);
            inorderTraversalForTterationList.add(root.val);
            inorderTraversalForTteration(root.right);
        }
        return inorderTraversalForTterationList;
    }

    /*************************************************前序遍歷**************************************************/

    /**
     * 前序遍歷 迭代 根左右
     * @param root
     * @return
     *
     */
    public static  List<Integer> inorderTraversal1(TreeNode root) {
        //
        List<Integer> list = new ArrayList<>();
        if (root == null) {
            return list;
        }
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while(cur != null || !stack.isEmpty()) {
            while(cur != null) {
                stack.push(cur);
                list.add(cur.val);
                cur = cur.left;
            }
            cur = stack.pop();
            cur = cur.right;
        }
        return list;
    }


    /**
     * 前序遍歷 遞歸版
     * @param args
     */
    private List<Integer> ans = new ArrayList<>();

    public List<Integer> preorderTraversal(TreeNode root) {
        // 遞歸版
        if(root == null) return ans;
        ans.add(root.val);
        if(root.left != null) preorderTraversal(root.left);
        if(root.right != null) preorderTraversal(root.right);
        return ans;
    }
    /***********************************************后序遍歷****************************************************/

    /**
     * 后序遍歷 迭代 左右根
     * @param root
     * @return
     */
    public static  List<Integer> inorderTraversal2(TreeNode root) {
        //
        List<Integer> list = new ArrayList<>();
        if (root == null) {
            return list;
        }
        Stack<TreeNode> s = new Stack<>();
        s.push(root);

        while( !s.isEmpty() ) {
            TreeNode node = s.pop(); // 1.出棧root
            if(node.left != null) {
                s.push(node.left); // 2.進棧 2,null,null
            }

            if(node.right != null) {
                s.push(node.right); // 3. 進棧 3,null,null
            }

            list.add(0, node.val); // 從最后插入依次插入 1 3 2 打印出來就是2 1 3
        }
        return list;
    }

    /**
     * 后序遍歷 遞歸
     */
    List<Integer> postorderTraversalList = new LinkedList<>();
    public List<Integer> postorderTraversal(TreeNode root) {
        if(root == null)
            return ans;
        postorderTraversal(root.left);
        postorderTraversal(root.right);
        postorderTraversalList.add(root.val);
        return ans;
    }


     /***********************************************層序遍歷*************************************************/
    /**
     *
     * @param root
     * @return
     */
     public static List<List<Integer>> levelOrder(TreeNode root) {
         List<List<Integer>> listList = new ArrayList<>();
         if(root == null) {
             return listList;
         }
         Queue<TreeNode> queue = new LinkedList<>();  // 練習(xí)了上面的題目,知道queue是先進先出就ok
         queue.add(root);
         while(!queue.isEmpty()) {
             int size = queue.size();
             List<Integer> list = new ArrayList<>();
             while(size > 0) {
                 TreeNode tempNode = queue.poll();
                 list.add(tempNode.val);
                 if(tempNode.left != null) {
                     queue.add(tempNode.left);
                 }
                 if(tempNode.right != null) {
                     queue.add(tempNode.right);
                 }
                 size--; // 從上到下,從左到右一個一個遍歷
             }
             listList.add(list);
         }
         return listList;
     }

    /***********************************************練習(xí)1:二叉樹的最大深度*************************************************/
    /**
     * 遞歸解法
     * @param root
     * @return
     */
    public static int maxDepth(TreeNode root) {
        if (root == null){
            return 0;
        } else {
            int left_depth = maxDepth(root.left);
            int right_depth = maxDepth(root.right);
            return Math.max(left_depth, right_depth) + 1;
        }
    }

    /**
     * 迭代解法
     * @param root
     * @return
     * 1.pair類似于map k,v結(jié)構(gòu)
     * 2.不同點:stack.peek 不改變棧的值(不刪除棧頂?shù)闹?,pop會把棧頂?shù)闹祫h除。 相同點:大家都返回棧頂?shù)闹怠?     * 總結(jié):left進棧,加深度(出現(xiàn)右節(jié)點的左子節(jié)點), right:出棧
     */
    public static int maxDepthInIteration(TreeNode root) {
        int depth = 0;
        //1.初始化一個棧
        Stack<Pair<TreeNode, Integer>> stack = new Stack<>();
        TreeNode p = root;
        int current_depth = 0;
        while(p !=null || !stack.isEmpty()){
            if(p!=null){
                stack.push(new Pair(p,++ current_depth)); // 1. stack=k:1,2,3 v:1  4. stack=2,null,null 2  14.3,null,null 2
                depth = Math.max(depth,current_depth); // 2. d=1  5. d=2  15. d=2
                p = p.left; // 3.stack = 2,null,null  6.stack null,null,null size=2  16.null,null,null
            }else{
                current_depth = stack.isEmpty()? 0:stack.peek().getValue(); // 7. cd=2  10. cd=1  17.cd=2
                p = stack.pop().getKey(); // 8.stack 2,null,null  11. stack 1,2,3  18.3,null,null
                p = p.right; // 9. stack null,null,null  12. stack 3,null,nul  19. null,null,null 此時p=null,stack.isEmpty=true
            }
        }
        return depth;
    }

    /***********************************************練習(xí)2:對稱二叉樹*************************************************/

    /**
     * 迭代  對稱是指對應(yīng)數(shù)值相對,不僅是結(jié)構(gòu)相對
     * @param root
     * @return
     */
    public static boolean isSymmetric(TreeNode root) {
        Queue<TreeNode> q = new LinkedList<>();
        q.add(root);
        q.add(root);
        while (!q.isEmpty()) {
            TreeNode t1 = q.poll();
            TreeNode t2 = q.poll();
            if (t1 == null && t2 == null) continue;
            if (t1 == null || t2 == null) return false;
            if (t1.val != t2.val) return false;
            // 順序有講究
            q.add(t1.left);
            q.add(t2.right);
            q.add(t1.right);
            q.add(t2.left);
        }
        return true;
    }

/*********************************************練習(xí)3:二叉樹路徑總合***************************************/
    /**
     * 給定一個二叉樹和一個目標(biāo)和,判斷該樹中是否存在根節(jié)點到葉子節(jié)點的路徑,這條路徑上所有節(jié)點值相加等于目標(biāo)和。
     * @param root
     * @param sum
     * @return   遞歸解法
     * 思路:      1            1.num - 1,2.num -2,3.左null, 4.右走||判斷,null 5.回到2,null,null,在回到1,2,3 6. 回到3,null,null
     *       2         3        7.走null,null,null兩次,回到3,null,null 結(jié)束
     *   null null  null null
     */
    public static  boolean hasPathSum(TreeNode root, int sum) {
        if(root == null) {
            return false;
        }
        if(root.val == sum && root.left == null && root.right == null) {
            return true;
        }
        sum -= root.val;
        return hasPathSum(root.left, sum) || hasPathSum(root.right, sum);

    }


    /*****************************************總結(jié)練習(xí)1:從中序與后序遍歷序列構(gòu)造二叉樹*********************************/
    /**
     * 例如,給出
     *
     * 中序遍歷 inorder = [9,3,15,20,7]
     * 后序遍歷 postorder = [9,15,7,20,3]
     * 返回如下的二叉樹:
     *
     *     3
     *    / \
     *   9  20
     *     /  \
     *    15   7
     *    關(guān)鍵點:  1.兩個數(shù)組的下標(biāo) 0 和 len-1,先找后序的根,根據(jù)根來區(qū)分中序的左子樹和右子樹
     *            2.左節(jié)點遞歸(0~根-1,0~后序左+左子樹-1)
     *            3.右節(jié)點遞歸(左子樹+1~中序右邊,后序左+左子樹~后序右-1)
     *
     */
    private static int[] inorder = {15,9, 12, 3, 15, 20, 7 }; // 中序遍歷 確定左右節(jié)點
    private static int[] postorder = { 15,12, 9, 15, 7, 20, 3 }; // 后序遍歷 確定根節(jié)點
    public static TreeNode buildTree(int[] inorder, int[] postorder) {
        TreeNode root = create(inorder, postorder, 0, inorder.length - 1, 0, postorder.length - 1);
        return root;
    }
    private static TreeNode create(int[] inorder, int[] postorder, int inLeft, int inRight, int postLeft, int postRight) {
        if(postLeft > postRight){
            return null;   // 16. 退回到上一顆數(shù)15,null,null
        }
        TreeNode treeNode = new TreeNode(postorder[postRight]); // 1. 先找后序最后一個數(shù),就是根節(jié)點   10.根節(jié)點為后序數(shù)組中的9 14.根是15
        int k = 0;
        for(int i = inLeft; i <= inRight; i++){ // 2.遍歷一下中序數(shù)組
            if(inorder[i] == postorder[postRight]){ // 3.  如果數(shù)據(jù)里的值 = 根節(jié)點
                k = i;  // 4.根節(jié)點下標(biāo)賦值給k = 3  11.根節(jié)點下標(biāo)1   15. 0
                break;
            }
        }
        int numLeft = k - inLeft; // 5.(左子樹的長度 = 3)在中序遍歷中找到根節(jié)點,左邊就是左子樹,右邊就是右子樹  12. 1
        // 6. 左節(jié)點遞歸(0~根-1,0~后序左+左子樹-1) 確定中序遍歷的左子樹的范圍,0~2,  13. 0~1-1,0~0+1-1
        // 7.根據(jù)后序遍歷特性:(左右根),根據(jù)第6步知道左子樹的范圍是0~2,所以在后序數(shù)組中的左子樹范圍也是0~2,并且知道下標(biāo)2是根節(jié)點,值為9
        // 8.postLeft + numLeft - 1    19.回到9,null,null
        treeNode.left = create(inorder, postorder, inLeft, k - 1, postLeft, postLeft + numLeft - 1);
        // 17. 右節(jié)點遞歸(左子樹+1~中序右邊,后序左+左子樹~后序右-1)此時左子樹為15,null,null 它的左子樹長度為0,所以要找左子樹右節(jié)點:會return
        treeNode.right = create(inorder, postorder, k + 1, inRight, postLeft + numLeft, postRight - 1);  // 20 回到9,15,null 繼續(xù)找左子樹12這個根節(jié)點
        return treeNode; // 18.執(zhí)行此步奏
    }

    /*****************************************總結(jié)練習(xí)2:二叉樹的最近公共祖先*********************************/
    /**
     * 給定一個二叉樹, 找到該樹中兩個指定節(jié)點的最近公共祖先。
     *
     * 百度百科中最近公共祖先的定義為:“對于有根樹 T 的兩個結(jié)點 p、q,最近公共祖先表示為一個結(jié)點 x,滿足 x 是 p、q 的祖先且 x 的深度盡可能大(一個節(jié)點也可以是它自己的祖先)。”
     *
     * 示例 1:
     *       3
     *    5    1
     *  6  2  0  8
     *    7 4
     * 輸入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
     * 輸出: 3
     * 解釋: 節(jié)點 5 和節(jié)點 1 的最近公共祖先是節(jié)點 3。
     * @param root
     * @param p
     * @param q
     * @return
     */
    public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        //遞歸出口
        if (root == null || root == p || root == q) {
            return root;
        }
        //去該節(jié)點的左子樹上找
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        //去該節(jié)點的右子樹上找
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        if (left == null) {
            //左子樹上沒有,說明在右子樹上
            return right;
        } else if (right == null) {
            //右子樹上沒有,說明在左子樹上
            return left;
        }
        //左右均有,說明該節(jié)點即為最近公共祖先
        return root;
    }


    /*****************************************總結(jié)練習(xí)3:二叉樹的序列化與反序列化*********************************/
    /**
     * 二叉樹的數(shù)的序列化和反序列化,二叉樹實際是存儲在內(nèi)存中的,一旦斷電或者是關(guān)機,二叉樹的數(shù)據(jù)就會在內(nèi)存中丟失。
     * 所以我們需要將二叉樹的數(shù)據(jù)保存下來,這個過程叫做持久化或者序列化;將二叉樹的數(shù)據(jù)保存到了磁盤之后,還需要將
     * 磁盤中的二叉樹的數(shù)據(jù)加載到內(nèi)存中去,這過程叫做反序列化。
     *
     * 解決思路:節(jié)點和節(jié)點之間使用,來分隔,空節(jié)點使用#來表示,為什么需要使用#來分隔?
     * 假如所有的節(jié)點都是相同的值,且不使用分隔符號,結(jié)構(gòu)不同也會序列化為相同的結(jié)果
     */
    public static String serialize(TreeNode root) {
        StringBuilder sb = new StringBuilder();
        encode(root, sb);
        return sb.toString();
    }

    private static void encode(TreeNode node, StringBuilder sb) {
        if (node == null) {
            sb.append("#,");
        } else {
            sb.append(node.val);
            sb.append(",");
            encode(node.left, sb);
            encode(node.right, sb);
        }
    }

    // Decodes your encoded data to tree.
    public static TreeNode deserialize(String data) {
        String[] vs = data.split(",");
        return decode(vs, new int[]{0});
    }

    private static TreeNode decode(String[] vs, int[] idx) {
        if (vs.length == 0 || idx[0] >= vs.length) {
            return null;
        }
        String s = vs[idx[0]];
        idx[0]++;
        if ("#".equals(s)) {
            return null;
        } else {
            int val = Integer.valueOf(s);
            TreeNode node = new TreeNode(val);
            node.left = decode(vs, idx);
            node.right = decode(vs, idx);
            return node;
        }
    }

    /*****************************************訓(xùn)練1:是否二叉樹搜索樹*********************************/
    /**
     * 二叉搜索樹具有以下性質(zhì):每個節(jié)點中的值必須大于(或等于)其左側(cè)子樹中的任何值,但小于(或等于)其右側(cè)子樹中的任何值。
     * 關(guān)鍵點:只要有任何一顆樹不滿足條件,在遞歸下去或者遞歸回來時將結(jié)果層層return
     */
    static Integer pre = null;


    public static boolean isValidBST(TreeNode root) {
        return invailInorderTraversal(root);
    }

    private static boolean invailInorderTraversal(TreeNode root){
        if(root == null){
            return true;
        }
        if(!invailInorderTraversal(root.left)){
            return false;
        }
        if(pre != null && root.val <= pre){  // 走左子樹 false時,根節(jié)點<= 左節(jié)點  走右子樹false時:右根節(jié)點<=右根父節(jié)點
            return false;
        }
        pre = root.val;
        if(!invailInorderTraversal(root.right)){
            return false;
        }
        return true;
    }

    /*****************************************訓(xùn)練1:二叉樹搜索樹搜索某個節(jié)點*********************************/
    /**
     * 給定二叉搜索樹(BST)的根節(jié)點和一個值。 你需要在BST中找到節(jié)點值等于給定值的節(jié)點。
     * 返回以該節(jié)點為根的子樹。 如果節(jié)點不存在,則返回 NULL。
     * @param root
     * @param val
     * @return
     */
    public static TreeNode searchBST(TreeNode root, int val) {

        if (root == null) {
            return null;
        }
        if (root.val == val) {
            return root;
        }
        else if (root.val > val) {
            return searchBST(root.left, val);
        }
        else {
            return searchBST(root.right, val);
        }
    }

    /*****************************************訓(xùn)練2:二叉樹搜索樹插入某個節(jié)點*********************************/
    public static TreeNode insertIntoBST(TreeNode root, int val) {
        if(root == null) {
            return new TreeNode(val);
        }
        // 大右小左
        if(root.val < val) {
            root.right = insertIntoBST(root.right, val);
        }else if(root.val > val) {
            root.left = insertIntoBST(root.left, val);
        }
        return root;
    }

     public static TreeNode insertIntoBST1(TreeNode root, int val) {
         if(root==null) return new TreeNode(val);
         TreeNode node = root;
         while(true)
         {
             if(node.val<val)
             {
                 if(node.right!=null) node = node.right;
                 else{
                     node.right = new TreeNode(val);
                     break;
                 }
             }
             else{
                 if(node.left!=null) node = node.left;
                 else{
                     node.left = new TreeNode(val);
                     break;
                 }
             }
         }
         return root;
     }


    /*****************************************訓(xùn)練3:二叉樹搜索樹刪除某個節(jié)點*********************************/
    public static TreeNode deleteNode(TreeNode root, int key) {
        if (!containNode(root, key)) {
            return root;
        }
        if (root.val == key) {
            if (root.left == null) {
                return root.right;
            } else if (root.right == null) {
                return root.left;
            }
            TreeNode successor = findMin(root.right); // 找到右邊最小的作為頭節(jié)點
            successor.right = delMin(root.right); //刪除掉這個最小節(jié)點,右邊就遍歷好了,在添加左邊就行了
            successor.left = root.left;//
            return successor;
        } else if (root.val < key) {
            root.right = deleteNode(root.right, key);
            return root;
        } else {
            root.left = deleteNode(root.left, key);
            return root;
        }
    }

    private static boolean containNode(TreeNode treeNode, int key) {
        if (treeNode == null) {
            return false;
        }
        if (treeNode.val == key) {
            return true;
        } else if (treeNode.val > key) {
            return containNode(treeNode.left, key);
        } else {
            return containNode(treeNode.right, key);
        }
    }

    /*
     * return a treeNode whose key is the minimum in the tree
     */
    private static TreeNode findMin(TreeNode treeNode) {
        TreeNode cur = treeNode;
        while (cur != null) {
            if (cur.left == null) {
                return cur;
            }
            cur = cur.left;
        }
        return cur;
    }

    /*
     * return a treeNode after deleting its treeNode whose key is the minimum
     */
    private static TreeNode delMin(TreeNode treeNode) {
        if (treeNode.left == null) {
            return treeNode.right;
        }
        treeNode.left = delMin(treeNode.left);
        return treeNode;
    }


    /*****************************************進階1:N叉樹的前序遍歷*********************************/
    /**
     *
     * @param root
     * @return
     */
    public static  List<Integer> preorder(Node root) {
        /*
        思路:前序遍歷是根左右,先遍歷根節(jié)點然后按順序遞歸遍歷孩子節(jié)點,當(dāng)沒有孩子節(jié)點時返回
         */
        List<Integer> res=new ArrayList<>();
        if (root==null)
        {
            return res;
        }
        preorder(root,res);
        return res;
    }

    private static void preorder(Node node,List<Integer> res)
    {
        res.add(node.val);
        List<Node> childList=node.children;
        if (childList.size()==0)
        {
            return;
        }else {
            for (int i = 0; i < childList.size(); i++) {
                preorder(childList.get(i),res);
            }
        }
    }




    /***********************************************main*************************************************/


    public static void main(String[] args) {
        TreeNode treeNode = new TreeNode(1);
        treeNode.left = new TreeNode(2);
        treeNode.right = new TreeNode(3);

        System.out.println("中序遍歷結(jié)果 = " + inorderTraversal(treeNode));
        System.out.println("前序遍歷結(jié)果 = " + inorderTraversal1(treeNode));
        System.out.println("后序遍歷結(jié)果 = " + inorderTraversal2(treeNode));
        System.out.println("層序遍歷結(jié)果 = " + levelOrder(treeNode));
        System.out.println("二叉樹的最大深度 = " + maxDepthInIteration(treeNode));
        System.out.println("對稱二叉樹 = " + isSymmetric(treeNode));
        System.out.println("二叉樹路徑總合 = " + hasPathSum(treeNode, 7));
        System.out.println("從中序與后序遍歷序列構(gòu)造二叉樹 中序顯示= " + inorderTraversal(buildTree(inorder, postorder)));
        System.out.println("二叉樹的最近公共祖先 = " + lowestCommonAncestor(treeNode, new TreeNode(2),new TreeNode(3)));
        System.out.println("二叉樹的序列化與反序列化 = " + serialize(treeNode));
        System.out.println("二叉樹的反序列化 中序顯示= " + inorderTraversal(deserialize("1,2,#,#,3,#,#,")));
        System.out.println("是否是二叉搜索樹 = " + isValidBST(treeNode));
        System.out.println("searchBST 二叉樹搜索樹搜索某個節(jié)點= " + searchBST(treeNode,3));
        System.out.println("二叉樹搜索樹插入某個節(jié)點  中序顯示= " + inorderTraversal(insertIntoBST(treeNode,4)));
    }

}
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }
}

class Node {
    int val;
    List<Node> children;

    Node(int x, List<Node> children) {
        val = x;
        children = children;
    }
}

歡迎關(guān)注我的微信公眾號<搜索:汀雨筆記>,會首發(fā)一些最新文章哦!

下面是我的個人網(wǎng)站:http://ransongv587.com

image
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容