当前位置: 首页 > 知识库问答 >
问题:

从深度优先搜索输出构造完美的二叉树

胥承
2023-03-14

假设你有一棵完美的二叉树,就像这样

         0
     /        \
    1           2      
   / \         / \
  3    4       5   6
 / \  / \    / \   / \
7  8 9  10 11  12 13 14 

给定其深度和作为深度优先搜索数组的节点值输出,例如。

深度:[4]

Dfs数组:[0,1,3,7,8,4,9,10,2,5,11,6,13,14]

编写将其作为二叉树返回的代码。你会怎么做(递归/非递归)?

我不确定是否有可能递归地解决这个问题,因为我不知道哪些节点是叶子而不是叶子。有了这些信息,人们就可以递归地构建树。在没有递归的情况下,我试图做一些类似的事情,但是我一直在做。

TreeNode {
    int value;
    TreeNode left;
    TreeNode right;

    TreeNode(int value) {
        this.value = value;
    }
}

TreeNode makeTree(int[] dfs, int depth) {
    TreeNode root = new TreeNode(dfs[0]);
    Deque<TreeNode> dq = new LinkedList<>();
    dq.addFirst(root);

    while (!dq.isEmpty()) {
        int i;
        for (i = 1; i < depth - 1; i++) {
           TreeNode t = dq.getFirst();
           t.left = new TreeNode(dfs[i]);
           dq.addFirst(t.left);
    }
    TreeNode t = dq.getFirst();
    t.left = new TreeNode(dfs[i++]);
    dq.addFirst(t.left);
    t.right = new TreeNode(dfs[i++)];
    dq.addFirst(t.right);
   }
   // More code here to construct the tree?
   .........
   // return the root
   return dq.getLast();
}

共有1个答案

东门深
2023-03-14

以下代码从表示dfs结果的数组构建二叉树。
注意注释,如果它们还不够,请毫不犹豫地询问:

public class GraphFromDfs{

    public static void main(String[] args) {

        int[] dfsArray = new int[]{0,1,3,7,8,4,9,10,2,5,11,12,6,13,14};
        TreeNode root = makeTree(dfsArray, 4);
        printTreeFromRoot(root);
    }

    private static TreeNode makeTree(int[] dfsArray, int depth) {

        //array to store all nodes
        TreeNode[] nodes = new TreeNode[dfsArray.length];

        //create all nodes from int[] array
        for(int i=0; i< dfsArray.length; i++) {
            nodes[i]= new TreeNode(dfsArray[i]); //nodes stored in the same order as int array
        }

        makeTree(nodes, depth);
        return nodes[0] ;
    }

    //process nodes to add links (create a tree)
    private static void makeTree(TreeNode[] nodes, int depth) {

        int currentDepth = 0;
        int index = 0; //index of node in nodes array
        TreeNode root = nodes[0];
        //stack all nodes to be processed. add root as first
        LinkedList<TreeNode> stack = new LinkedList<>();
        stack.add(root);

        while (! stack.isEmpty()) {

            TreeNode node = stack.peekLast();

            if(node.left == null) { node.left = nodes[++index]; }         //process left or right if
            else if (node.right == null) { node.right = nodes[++index]; } //any is null. update index

            //add next node to stack to be processed if not a leaf.
            //leaf does not need to be processed
            if((currentDepth +2) < depth ) {

                stack.add(nodes[index]);
                currentDepth++;

            //if leaf - backtrack. move up the tree
            //note that this is in line with "perfect binary tree" as asked
            }else if((node.right != null) && (node.left != null)) {

                while (! stack.isEmpty()) {
                    TreeNode n = stack.peekLast();
                    if((n.left != null) && (n.right != null)) {
                        stack.remove(n); //remove fully processed nodes
                                         //(right and left are not null)
                        currentDepth --; //backtrack
                    }else {
                        break;
                    }
                }
            }
        }
    }

    private static void printTreeFromRoot(TreeNode root) {

        if(root == null) { return;}
        System.out.println("--------- TREE  ---------");
        System.out.println( root);
        printTree(root);
        System.out.println("--------------------------");
    }

    //recursive tree print
    private static void printTree(TreeNode root) {

        if(root.left != null ) {
            System.out.println( root.left);
            printTree(root.left);
        }
        if(root.right != null ) {
            System.out.println( root.right);
            printTree(root.right);
        }
    }
}

class TreeNode {

    int value;
    TreeNode left, right;

    TreeNode(int value) {
        this.value = value;
    }

    @Override
    public String toString() {

        StringBuilder s = new StringBuilder("N:"+ value);
        s.append( left == null ? " L-null" : " L-"+left.value);
        s.append( right == null ? " R-null" : " R-"+right.value);
        return s.toString();
    }
}

输出

 类似资料:
  • 主要内容:深度优先搜索(简称“深搜”或DFS),广度优先搜索,总结前边介绍了有关图的 4 种存储方式,本节介绍如何对存储的图中的顶点进行遍历。常用的遍历方式有两种: 深度优先搜索和 广度优先搜索。 深度优先搜索(简称“深搜”或DFS) 图 1 无向图 深度优先搜索的过程类似于树的先序遍历,首先从例子中体会深度优先搜索。例如图 1 是一个无向图,采用深度优先算法遍历这个图的过程为: 首先任意找一个未被遍历过的顶点,例如从 V1 开始,由于 V1 率先访问过了,所以

  • 本文向大家介绍深度优先搜索,包括了深度优先搜索的使用技巧和注意事项,需要的朋友参考一下 图遍历是按某种系统顺序访问图的所有顶点的问题。遍历图主要有两种方法。 广度优先搜索 深度优先搜索 深度优先搜索(DFS)算法从顶点v开始,然后遍历到之前未访问过的相邻顶点(例如x),并将其标记为“已访问”,然后继续处理x的相邻顶点,依此类推。 如果在任何一个顶点上遇到所有相邻顶点都被访问过,则它将回溯直到找到具

  • 3. 深度优先搜索 现在我们用堆栈解决一个有意思的问题,定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, }; 它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的路线

  • 主要内容:src/runoob/binary/Traverse.java 文件代码:二分搜索树遍历分为两大类,深度优先遍历和层序遍历。 深度优先遍历分为三种:先序遍历(preorder tree walk)、中序遍历(inorder tree walk)、后序遍历(postorder tree walk),分别为: 1、前序遍历:先访问当前节点,再依次递归访问左右子树。 2、中序遍历:先递归访问左子树,再访问自身,再递归访问右子树。 3、后序遍历:先递归访问左右子树,再访问自身节

  • 我们可以使用前序遍历输出构造唯一的二叉查找树,如下所示: 第一个元素将是根。 左子元素=小于根的最近元素。 右子元素=最近的元素大于根。 这些事实很容易转换成代码。然而,我正在努力获得如此严格的事实/步骤,以将级别顺序遍历输出转换为唯一的二叉查找树。 例如,如果我有以下级别顺序遍历输出,我可以形成BST如下: 级别顺序遍历中的第一个元素始终是根(级别0)。然后是级别1的元素。4小于5,所以我将把它

  • 二叉树上广度优先搜索的空间复杂度是多少?因为它一次只存储一个级别,我不认为它会是O(n)。