[英]how to build a binary tree from preorder and inorder traversals
Im doing an assignment on building a binary tree from the preorder and inorder traversals (a char in each Node) and im trying to wrap my brain around how to build the actual tree. 我正在做一个关于从预订和顺序遍历(每个节点中的一个字符串)构建二叉树的任务,并试图围绕如何构建实际树包裹我的大脑。
Here is my thought process on how to accomplish this: 以下是关于如何实现此目标的思考过程:
I have steps 1-4 taken care of, but im not too sure how to properly build my tree, and was wondering if anyone had any pointers. 我已经完成了步骤1-4,但是我不太确定如何正确构建我的树,并且想知道是否有人有任何指针。 Thank you.
谢谢。
Do the recursion before building the new tree. 在构建新树之前执行递归。 So, your list would look like this:
所以,你的列表看起来像这样:
The non-recursive parts can be done in O(n) overall, and summing them up for each recursion level is also O(n) each. 非递归部分可以在O(n)中完成,并且对于每个递归级别对它们求和也是每个O(n)。 The total runtime thus depends on the number of recursion levels.
因此总运行时间取决于递归级别的数量。 If you have a approximately balanced tree, the depth is O(log n), thus we get to O(n · log n) at all.
如果你有一个近似平衡的树,深度是O(log n),因此我们得到O(n·log n)。 As the only necessarily slow part is the search of the root node in the inorder array, I guess we could optimize that even a bit more if we know more about the tree.
由于唯一缓慢的部分是在inorder数组中搜索根节点,我想如果我们对树有更多的了解,我们可以优化它。
In the worst case we have one recursion level for each node in the tree, coming to complexity O(n·n). 在最坏的情况下,我们在树中的每个节点都有一个递归级别,达到复杂度O(n·n)。
Example: Preorder ABCDEF, Inorder FEDCBA, Tree: 示例:预购ABCDEF,Inorder FEDCBA,树:
+---+
| A |
++--+
|
+---+ |
| B +<--+
++--+
|
+---+ |
| C +<--+
++--+
|
+---+ |
| D +<--+
++--+
|
+---+ |
| E +<--+
++--+
|
+---+ |
| F +<--+
+---+
You can use the below code, I just wrote for the same problem. 你可以使用下面的代码,我刚刚写了同样的问题。 It works for me.
这个对我有用。
public class TreeFromInorderAndPreOrder {
public static List<Integer> inOrder = new ArrayList<Integer>();
public static List<Integer> preOrder = new ArrayList<Integer>();
public static void main(String[] args) {
Node root = new Node();
root.createRoot(5);
for(int i = 0 ; i < 9 ; i++){
if(i != 5){
root.insert(i);
}
}
inOrder(root);
preOrder(root);
for(Integer temp : inOrder){
System.out.print(temp + " ");
}
System.out.println();
for(Integer temp : preOrder){
System.out.print(temp + " ");
}
Node node1 = null;
node1 = reConstructTree(root, (ArrayList<Integer>) inOrder, true);
System.out.println();
inOrder(node1);
for(Integer temp : inOrder){
System.out.print(temp + " ");
}
System.out.println();
for(Integer temp : preOrder){
System.out.print(temp + " ");
}
}
public static void inOrder(Node node){
if(node!= null){
inOrder(node.leftchild);
inOrder.add(node.key);
inOrder(node.rightChild);
}
}
public static void preOrder(Node node){
if(node != null){
preOrder.add(node.key);
preOrder(node.leftchild);
preOrder(node.rightChild);
}
}
public static Node reConstructTree(Node root, ArrayList<Integer> inOrder,
boolean isLeft){
if(preOrder.size() != 0 && inOrder.size() != 0){
return null;
}
Node node = new Node();
node.createRoot(preOrder.get(0));
if(root != null && isLeft){
root.leftchild = node;
}else if(root != null && !isLeft){
root.rightChild = node;
}
int indx = inOrder.get(preOrder.get(0));
preOrder.remove(0);
List<Integer> leftInorder = getSublist(0, indx);
reConstructTree(node, (ArrayList<Integer>) leftInorder, true);
List<Integer> rightInorder = getSublist(indx+1, inOrder.size());
reConstructTree(node, (ArrayList<Integer>)rightInorder, false);
return node;
}
public static ArrayList<Integer> getSublist(int start, int end){
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i = start ; i < end ; i++){
list.add(inOrder.get(i));
}
return list;
}
}
I have written a sample program using divide and conquer approach using recursion in java 我已经使用java中的递归使用分而治之的方法编写了一个示例程序
import java.util.LinkedList;
import java.util.Queue;
public class BinaryTreeNode {
private char data;
public char getData() {
return data;
}
public void setData(char data) {
this.data = data;
}
public BinaryTreeNode getLeft() {
return left;
}
public void setLeft(BinaryTreeNode left) {
this.left = left;
}
public BinaryTreeNode getRight() {
return right;
}
public void setRight(BinaryTreeNode right) {
this.right = right;
}
private BinaryTreeNode left;
private BinaryTreeNode right;
public static void levelTravesal(BinaryTreeNode node)
{
Queue queue = new LinkedList();
if(node == null)
return;
queue.offer(node);
queue.offer(null);
int level =0;
while(!queue.isEmpty())
{
BinaryTreeNode temp = (BinaryTreeNode) queue.poll();
if(temp == null)
{
System.out.println("Level: "+level);
if(!queue.isEmpty())
queue.offer(null);
level++;
}else {
System.out.println(temp.data);
if(temp.getLeft()!=null)
queue.offer(temp.getLeft());
if(temp.getRight()!=null)
queue.offer(temp.getRight());
}
}
}
static int preIndex = 0;
public static void main(String[] args) {
if(args.length < 2)
{
System.out.println("Usage: preorder inorder");
return;
}
char[] preOrderSequence = args[0].toCharArray();
char[] inOrderSequence = args[1].toCharArray();
//char[] preOrderSequence = {'A','B','D','E','C','F'};
//char[] inOrderSequence = "DBEAFC".toCharArray();
if(preOrderSequence.length != inOrderSequence.length)
{
System.out.println("Pre-order and in-order sequences must be of same length");
return;
}
BinaryTreeNode root = buildBinaryTree(preOrderSequence, inOrderSequence, 0, preOrderSequence.length-1);
System.out.println();
levelTravesal(root);
}
static BinaryTreeNode buildBinaryTree(char[] preOrder, char[] inOrder, int start, int end)
{
if(start > end)
return null;
BinaryTreeNode rootNode = new BinaryTreeNode();
rootNode.setData(preOrder[preIndex]);
preIndex++;
//System.out.println(rootNode.getData());
if(start == end)
return rootNode;
int dataIndex = search(inOrder, start, end, rootNode.getData());
if(dataIndex == -1)
return null;
//System.out.println("Left Bounds: "+start+" "+(dataIndex-1));
rootNode.setLeft(buildBinaryTree(preOrder, inOrder, start, dataIndex - 1));
//System.out.println("Right Bounds: "+(dataIndex+1)+" "+end);
rootNode.setRight(buildBinaryTree(preOrder, inOrder, dataIndex+1, end));
return rootNode;
}
static int search(char[] inOrder,int start,int end,char data)
{
for(int i=start;i<=end;i++)
{
if(inOrder[i] == data)
return i;
}
return -1;
}
}
Here is a mathematical approach to achieve the thing in a very simplistic way : 这是一种以非常简单的方式实现事物的数学方法:
Language used : Java 使用的语言:Java
` `
/* Algorithm for constructing binary tree from given Inorder and Preorder traversals. / *从给定的Inorder和Preorder遍历构造二叉树的算法。 Following is the terminology used :
以下是使用的术语:
i : represents the inorder array supplied i:表示提供的inorder数组
p : represents the preorder array supplied p:表示提供的预订单数组
beg1 : starting index of inorder array beg1:inorder数组的起始索引
beg2 : starting index of preorder array beg2:预编程数组的起始索引
end1 : ending index of inorder array end1:inorder数组的结束索引
end2 : ending index of preorder array end2:预订单数组的结束索引
*/ * /
public static void constructTree(Node root, int[] i, int[] p, int beg1, int end1, int beg2, int end2) public static void constructTree(Node root,int [] i,int [] p,int beg1,int end1,int beg2,int end2)
{ {
if(beg1==end1 && beg2 == end2)
{
root.data = i[beg1];
}
else if(beg1<=end1 && beg2<=end2)
{
root.data = p[beg2];
int mid = search(i, (int) root.data);
root.left=new Node();
root.right=new Node();
constructTree(root.left, i, p, beg1, mid-1, beg2+1, beg2+mid-beg1);
System.out.println("Printing root left : " + root.left.data);
constructTree(root.right, i, p, mid+1, end1, beg2+1+mid-beg1, end2);
System.out.println("Printing root left : " + root.right.data);
}
} }
` `
You need invoke the function by following code : 您需要通过以下代码调用该函数:
int[] i ={4,8,7,9,2,5,1,6,19,3,18,10}; //Inorder
int[] p ={1,2,4,7,8,9,5,3,6,19,10,18}; //Preorder
Node root1=new Node();
constructTree(root1, i, p, 0, i.length-1, 0, p.length-1);
In case you need a more elaborate explanation of code please mention it in the comments. 如果您需要更详细的代码说明,请在评论中提及。 I would be happy to help :).
我很乐意帮助:)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.