Arrays 将链接二叉树转换为基于数组的二叉树

Arrays 将链接二叉树转换为基于数组的二叉树,arrays,data-structures,binary-tree,Arrays,Data Structures,Binary Tree,如何将最初作为链接结构实现的二叉树转换为基于数组的二叉树 如果二叉树类似于这样一个完整的二叉树,则不会有问题: 5 / \ / \ / \ 3 7 / \ / \ 1 4 6 9 因为我可以使用宽度优先遍历在数组中连续添加节点 但是如果它是一棵不完整的树呢 5 / \ / \ / \ 3 7 \ / \ 4 6

如何将最初作为链接结构实现的二叉树转换为基于数组的二叉树

如果二叉树类似于这样一个完整的二叉树,则不会有问题:

      5
     / \
    /   \
   /     \ 
  3       7
 / \     / \
1   4   6   9
因为我可以使用宽度优先遍历在数组中连续添加节点

但是如果它是一棵不完整的树呢

      5
     / \
    /   \
   /     \ 
  3       7
   \     / \
    4   6   9

      5
       \
        \
         \ 
          7
         / \
        6   9

       5
      / \
     /   \
    /     \ 
   3       7
    \  
     4
有些节点没有任何子节点,或者其子节点计数不完全为2。如何将其转换为数组

如何以这种方式将不完整的二叉树示例添加到数组中:

1st: 5 3 7 null 4 6 9
2nd: 5 null 7 null null 6 9
3rd: 5 3 7 null 4 null null

为了做到这一点,我们可以使用二叉树的水平顺序遍历,并进行一些修改

通常在水平顺序遍历中,我们只添加那些非空的树节点,以避免无限循环。但在这种情况下,因为您希望打印所有级别的元素,直到某个级别甚至不包含单个非空节点

为了实现这一点,我们可以维护一个
count
变量,该变量跟踪队列中存在多少个非空节点,并且当从队列中弹出一个非空节点时,
count
将递减。此外,在队列中,无论父节点是空节点还是非空节点,我们都必须同时添加左节点和右节点

如果弹出的父节点为空,则通过在队列(如果部分)中将其左、右子节点添加为空来分别处理该节点;否则,如果父节点不为空,则减少计数并添加其左、右子节点,同时根据左、右节点的非空节点数增加计数。
count
。(否则部分)

此外,除了计数外,我们还必须维护特定级别的节点数量。我们之所以使用它,是因为如果partular级别的count变为0,那么我们必须打印该级别的所有剩余节点(为null)。因此,我们需要知道有多少节点仍然存在于该级别

这可以从示例3中得到解释。在第3级(如果根级别是第1级),当我们到达值为4的节点时,我们的计数将变为0,我们将退出循环,而不打印该级别的剩余节点值(null,null)。为了跟踪每个级别上有多少节点,我们使用变量
levelnode
currenlevelnode

以下是相同的工作示例:

    private static List<String> levelorderTraversal(Node root) {
            Queue<Node> queue = new LinkedList<Node>();
            queue.add(root);
            Node node;
            int count=1;
            int levelnode=1, currlevelnode=0;
            List<String> result = new ArrayList<String>();
            while(count>0) {  //count represents number of non null nodes in queue
                node = queue.poll();
                if(levelnode == 0) { //if we have reached to next level
                   levelnode=currlevelnode;
                   currlevelnode = 0;
                }
                if(node==null) { //if parent node is null
                    result.add(null);
                    queue.add(null); //add its left child as null
                    queue.add(null); //add its right child as null
                } else {
                    count--;  //since we have popped out non null node decrement count
                    result.add(Integer.toString(node.val));
                    if(node.left != null) { //increment count if any of the left / right child is non null
                        count++;
                    }
                    if(node.right != null) { 
                        count++;
                    }
                    queue.add(node.left); //add left child of parent node
                    queue.add(node.right); // add right child of parent node
                }
                currlevelnode+=2;
                levelnode--;
            }
            while(levelnode>0) { //if at last level still nodes are left to be added
               result.add(null);
               levelnode--;
            }
            return result;
   }
private静态列表levelorderTraversal(节点根){
Queue Queue=new LinkedList();
添加(根);
节点;
整数计数=1;
int-levelnode=1,currenlevelNode=0;
列表结果=新建ArrayList();
而(count>0){//count表示队列中非空节点的数量
node=queue.poll();
如果(levelnode==0){//如果我们已经到达下一个级别
levelnode=currlevelnode;
currlevelnode=0;
}
如果(node==null){//如果父节点为null
结果.添加(空);
queue.add(null);//将其左子级添加为null
queue.add(null);//将其右子级添加为null
}否则{
count--;//因为我们弹出了非空节点递减计数
add(Integer.toString(node.val));
如果(node.left!=null){//如果左/右子节点中的任何一个非null,则递增计数
计数++;
}
如果(node.right!=null){
计数++;
}
queue.add(node.left);//添加父节点的左子节点
queue.add(node.right);//添加父节点的右子节点
}
currlevelnode+=2;
levelnode--;
}
while(levelnode>0){//if在最后一级仍然保留要添加的节点
结果.添加(空);
levelnode--;
}
返回结果;
}

@robert如果您有任何与解决方案相关的问题,请告诉我。