先序和中序遍历的二叉树

发布于 2024-10-31 06:48:30 字数 216 浏览 1 评论 0原文

如何从这些前/中顺序遍历中获取树:

Pre: A,B,D,E,C,F,G,H 在:E,D,B,A,G,F,H,C

编辑:我的答案

       A
      / \
     B   C
    /     \
   D       F
  /       / \
 E       G   H

How can I get the tree form these pre/in order traversal:

Pre: A,B,D,E,C,F,G,H
in:E,D,B,A,G,F,H,C

EDITED: MY Answer

       A
      / \
     B   C
    /     \
   D       F
  /       / \
 E       G   H

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

转身以后 2024-11-07 06:48:30

编辑:
更正,

您没有正确的答案,FGH 在 C 的左侧。

要验证,只需针对它运行两个算法:

PreOrder(node)
  if node is null return
  Print(node)
  PreOrder(node.left)
  PreOrder(node.Right)

InOrder(node)
  if node is null return
  InOrder(node.left)
  Print(node)
  InOrder(node.Right)

您知道 A 是根,因为它启动了预序。使用中序将节点排列在 A 的左侧和右侧。B 是第二个节点(前序),A 的左侧(中序),依此类推。

你知道 F,G,H 是 C 的左边,因为按顺序排列。

基本上,使用预序来选择下一个节点,并按序查看它是在父节点的左侧还是右侧。

编辑(2011 年 4 月 18 日)

为了展示这个过程的机械性,我提供了这个伪代码:

// Add method on binary tree class -- stock standard
method Add(item, comparer)
  newNode = new Node(item)
  parent = null

  // Find suitable parent
  currentNode = root
  while currentNode is not null
    parent = currentNode
    if comparer(newNode.Key, currentNode.Key) < 0
      currentNode = currentNode.Left
    else 
      currentNode = currentNode.Right

  // Add new node to parent
  if parent is null
    root = newNode
  else if comparer(newNode.Value, parent.Value) < 0 
    parent.Left = newNode
  else 
    parent.Right = newNode

技巧是使用有序序列来确定节点是否添加到它的父级,例如:

// Client code
// Input arrays
var preOrder = ["A","B","D","E","C","F","G","H"]
var inOrder  = ["E","D","B","A","G","F","H","C"]
// A collection associating the Key value with its position in the inOrder array
var inOrderMap = GetInOrderMap(inOrder)

// Build tree from pre-order and in-order sequences
foreach (item in preOrder) 
  Add(item, fun (l, r) -> inOrderMap[l] - inOrderMap[r])

我正在传递一个lambda,但任何传递比较器的等效方法都应该这样做。

EDIT:
Correction,

You don't have the correct answer, FGH is to the left of C.

To verify just run the two algorithms against it:

PreOrder(node)
  if node is null return
  Print(node)
  PreOrder(node.left)
  PreOrder(node.Right)

InOrder(node)
  if node is null return
  InOrder(node.left)
  Print(node)
  InOrder(node.Right)

You know that A is the root because it starts the pre-order. Use the in-order to arrange nodes to the left and right of A. B is the second node (pre-order), and left of A (in-order), and so on.

You know that F,G,H is left of C because of the in-order arrangement.

Basically, use preorder to select the next node, and in-order to see whether it is left or right of the parent node.

EDIT (18 Apr 2011):

To show how mechanical the process is I offer this pseudo code:

// Add method on binary tree class -- stock standard
method Add(item, comparer)
  newNode = new Node(item)
  parent = null

  // Find suitable parent
  currentNode = root
  while currentNode is not null
    parent = currentNode
    if comparer(newNode.Key, currentNode.Key) < 0
      currentNode = currentNode.Left
    else 
      currentNode = currentNode.Right

  // Add new node to parent
  if parent is null
    root = newNode
  else if comparer(newNode.Value, parent.Value) < 0 
    parent.Left = newNode
  else 
    parent.Right = newNode

The trick is to use the in-order sequence to determine whether a node is added to the left or right of its parent, for example:

// Client code
// Input arrays
var preOrder = ["A","B","D","E","C","F","G","H"]
var inOrder  = ["E","D","B","A","G","F","H","C"]
// A collection associating the Key value with its position in the inOrder array
var inOrderMap = GetInOrderMap(inOrder)

// Build tree from pre-order and in-order sequences
foreach (item in preOrder) 
  Add(item, fun (l, r) -> inOrderMap[l] - inOrderMap[r])

I'm passing a lamba, but any equivalent method for passing a comparer should do.

避讳 2024-11-07 06:48:30

这是一种以非常简单的方式实现这一目标的数学方法:

使用的语言:Java

`
/*
从给定的中序和先序遍历构造二叉树的算法。
以下是使用的术语:

i :表示提供的中序数组

p :表示提供的前序数组

beg1 :中序数组的起始索引

beg2 :前序数组的起始索引

end1 :中序数组的结束索引

end2 :前序数组的结束索引

*/

public static void ConstructionTree(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);
}

}

`

您需要通过以下代码调用该函数:

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);

如果您需要更详细的解释代码请在评论中提及。我很乐意提供帮助:)。

Here is a mathematical approach to achieve the thing in a very simplistic way :

Language Used : Java

`
/*
Algorithm for constructing binary tree from given Inorder and Preorder traversals.
Following is the terminology used :

i : represents the inorder array supplied

p : represents the preorder array supplied

beg1 : starting index of inorder array

beg2 : starting index of preorder array

end1 : ending index of inorder array

end2 : ending index of preorder array

*/

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 :).

苏佲洛 2024-11-07 06:48:30

下面是 C# 中的一个工作实现

public static class TreeUtil
{
   public static BinarySearchTree<T> FromTraversals<T>(T[] preorder, T[] inorder)
   {
       if (preorder == null) throw new ArgumentNullException("preorder");
       if (inorder == null) throw new ArgumentNullException("inorder");
       if (preorder.Length != inorder.Length) throw new ArgumentException("inorder and preorder have different lengths");

       int n = preorder.Length;
       return new BinarySearchTree<T>(FromTraversals(preorder, 0, n - 1, inorder, 0, n - 1));
   }

   public static BinaryTreeNode<T> FromTraversals<T>(T[] preorder, int pstart, int pend, T[] inorder, int istart, int iend)
   {
       if (pstart > pend) return null;

       T rootVal = preorder[pstart];
       int rootInPos;
       for (rootInPos = istart; rootInPos <= iend; rootInPos++) //find rootVal in inorder
           if (Comparer<T>.Default.Compare(inorder[rootInPos], rootVal) == 0) break;

       if (rootInPos > iend)
           throw new ArgumentException("invalid inorder and preorder inputs");

       int offset = rootInPos - istart;
       return new BinaryTreeNode<T>(rootVal)
           {
               Left = FromTraversals(preorder, pstart + 1, pstart + offset, inorder, istart, istart + offset - 1),
               Right = FromTraversals(preorder, pstart + offset + 1, pend, inorder, istart + offset + 1, iend),
           };
   }
}

这是 BinarySearchTreeBinaryTreeNode的一种可能实现T>。一些测试:

[TestMethod]
public void TestGenerationFromTraversals()
{
  var preorder = new[] {1, 2, 4, 5, 3};
  var inorder = new[] {4, 2, 5, 1, 3};
  AssertGenerationFromTraversal(preorder, inorder);

  var preorder2 = new[] { 'A', 'B', 'D', 'E', 'C', 'F' };
  var inorder2 = new[] { 'D', 'B', 'E', 'A', 'F', 'C' };
  AssertGenerationFromTraversal(preorder2, inorder2);
}

private static void AssertGenerationFromTraversal<T>(T[] preorder, T[] inorder)
{
  var tree = BinarySearchTreeUtil.FromTraversals(preorder, inorder);

  var treeInorder = new List<T>();
  tree.TraverseInOrder(treeInorder.Add);
  var treePre = new List<T>();
  tree.TraversePreOrder(treePre.Add);

  Assert.IsTrue(preorder.SequenceEqual(treePre));
  Assert.IsTrue(inorder.SequenceEqual(treeInorder));
}

Below is a working implementation in C#

public static class TreeUtil
{
   public static BinarySearchTree<T> FromTraversals<T>(T[] preorder, T[] inorder)
   {
       if (preorder == null) throw new ArgumentNullException("preorder");
       if (inorder == null) throw new ArgumentNullException("inorder");
       if (preorder.Length != inorder.Length) throw new ArgumentException("inorder and preorder have different lengths");

       int n = preorder.Length;
       return new BinarySearchTree<T>(FromTraversals(preorder, 0, n - 1, inorder, 0, n - 1));
   }

   public static BinaryTreeNode<T> FromTraversals<T>(T[] preorder, int pstart, int pend, T[] inorder, int istart, int iend)
   {
       if (pstart > pend) return null;

       T rootVal = preorder[pstart];
       int rootInPos;
       for (rootInPos = istart; rootInPos <= iend; rootInPos++) //find rootVal in inorder
           if (Comparer<T>.Default.Compare(inorder[rootInPos], rootVal) == 0) break;

       if (rootInPos > iend)
           throw new ArgumentException("invalid inorder and preorder inputs");

       int offset = rootInPos - istart;
       return new BinaryTreeNode<T>(rootVal)
           {
               Left = FromTraversals(preorder, pstart + 1, pstart + offset, inorder, istart, istart + offset - 1),
               Right = FromTraversals(preorder, pstart + offset + 1, pend, inorder, istart + offset + 1, iend),
           };
   }
}

Here is one possible implementation of BinarySearchTree<T> and BinaryTreeNode<T>. Some tests:

[TestMethod]
public void TestGenerationFromTraversals()
{
  var preorder = new[] {1, 2, 4, 5, 3};
  var inorder = new[] {4, 2, 5, 1, 3};
  AssertGenerationFromTraversal(preorder, inorder);

  var preorder2 = new[] { 'A', 'B', 'D', 'E', 'C', 'F' };
  var inorder2 = new[] { 'D', 'B', 'E', 'A', 'F', 'C' };
  AssertGenerationFromTraversal(preorder2, inorder2);
}

private static void AssertGenerationFromTraversal<T>(T[] preorder, T[] inorder)
{
  var tree = BinarySearchTreeUtil.FromTraversals(preorder, inorder);

  var treeInorder = new List<T>();
  tree.TraverseInOrder(treeInorder.Add);
  var treePre = new List<T>();
  tree.TraversePreOrder(treePre.Add);

  Assert.IsTrue(preorder.SequenceEqual(treePre));
  Assert.IsTrue(inorder.SequenceEqual(treeInorder));
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文