【问题标题】:How to create a binary tree如何创建二叉树
【发布时间】:2010-10-24 03:00:38
【问题描述】:

我不是指二叉搜索树。

例如, 如果我将值 1,2,3,4,5 插入到二叉搜索树中,则中序遍历将给出 1,2,3,4,5 作为输出。

但是如果我将相同的值插入到二叉树中,则中序遍历应该给出 4,2,5,1,3 作为输出。

可以使用动态数组创建二叉树,其中对于索引 n 中的每个元素, 2n+1 和 2n+2 分别代表它的左右孩子。

所以表示和级别顺序遍历在这里非常容易。

但我认为,中单、后单、预单很难。

我的问题是我们如何创建像二叉搜索树一样的二叉树。 IE。 有一个包含数据、左右指针而不是数组的树类。 这样我们就可以递归地进行遍历。

【问题讨论】:

  • 你的“二叉树”真的是堆吗?如果是这样,为什么需要按顺序遍历?
  • 您是否在 Google 上搜索过“二叉树源”?
  • 不是特定语言,不是堆(所以它不是很有用,我知道 :-))它是一个完整的二叉树。
  • 这个问题对我来说是 CS 家庭作业,嘿嘿。
  • 他想要一棵二叉树,它被实现为平面数组,而不是指针。

标签: c# data-structures binary-tree


【解决方案1】:

树类声明部分当然不是这里的难点。您在问题中基本上说明了如何声明它:

class BinaryTree
{
private:
    int data;
    BinaryTree *left, *right;
};

这支持各种形式的遍历,像这样:

void Inorder(const BinaryTree *root)
{
  if(root == 0)
    return;
  Inorder(root->left);
  printf("now at %d\n", root->data);
  Inorder(root->right);
}

您应该能够从中推断出订单前和订单后的遍历。在实际实现中,树可能会被模板化以存储随机数据,遍历例程会更通用(使用用户数据输入,或者可能是用户提供的每个节点回调,或其他),当然。

【讨论】:

  • 好的,一旦我们有了上述格式的树.. 遍历就很容易了。但是如何以上述格式创建树(在二叉搜索树中,我们可以比较元素并相应地将它们放入左侧或右侧,但这里我们不做任何比较..我们必须将树构建为完整的树。如果有错误请纠正我。
【解决方案2】:

由于我没有收到我提出的问题的任何答案,我将发布我自己使用数组实现的二叉树。 现在我知道数组实现比我想象的要容易,但我仍然不知道如何使用链表来实现。

代码在c#中

  class BinaryTree
    {
        private static int MAX_ELEM = 100;      //initial size of the array
        int lastElementIndex;
        int?[] dataArray;

        public BinaryTree()
        {
            dataArray = new int?[MAX_ELEM];
            lastElementIndex = -1;
        }

        //function to insert data in to the tree
        //insert as a complete binary tree
        public void insertData(int data)
        {
            int?[] temp;
            if (lastElementIndex + 1 < MAX_ELEM)
            {
                dataArray[++lastElementIndex] = data;
            }
            else
            {  //double the size of the array on reaching the limit
                temp = new int?[MAX_ELEM * 2];
                for (int i = 0; i < MAX_ELEM; i++)
                {
                    temp[i] = dataArray[i];
                }
                MAX_ELEM *= 2;
                dataArray = temp;
                dataArray[++lastElementIndex] = data;
            }
        }

        //internal function used to get the left child of an element in the array
        int getLeftChild(int index) {
            if(lastElementIndex >= (2*index+1))
                return (2*index + 1);
            return -1;
        }

        //internal function used to get the right child of an element in the array
        int getRightChild(int index) {
            if(lastElementIndex >= (2*index+2))
                return (2*index + 2);
            return -1;
        }
        //function to check if the tree is empty
        public bool isTreeEmpty() {
            if (lastElementIndex == -1)
                return true;
            return false;
        }

        //recursive function for inorder traversal
        public void traverseInOrder(int index) {
            if (index == -1)
                return;
            traverseInOrder(getLeftChild(index));
            Console.Write("{0} ", dataArray[index]);
            traverseInOrder(getRightChild(index));
        }

        //recursive function for preorder traversal
        public void traversePreOrder(int index) {
            if (index == -1)
                return;
            Console.Write("{0} ", dataArray[index]);
            traversePreOrder(getLeftChild(index));
            traversePreOrder(getRightChild(index));
        }

        //recursive function for postorder traversal
        public void traversePostOrder(int index) {
            if (index == -1)
                return;
            traversePostOrder(getLeftChild(index));
            traversePostOrder(getRightChild(index));
            Console.Write("{0} ", dataArray[index]);
        }

        //function to traverse the tree in level order
        public void traverseLevelOrder()
        {
            Console.WriteLine("\nPrinting Elements Of The Tree In Ascending Level Order\n");
            if (lastElementIndex == -1)
            {
                Console.WriteLine("Empty Tree!...press any key to return");
                Console.ReadKey();
                return;
            }
            for (int i = 0; i <= lastElementIndex; i++)
            {
                Console.Write("{0} ", dataArray[i]);
            }
            Console.WriteLine("\n");
        }


    }

【讨论】:

    【解决方案3】:

    如果我理解正确,您想从数组创建二叉树

    int[] values = new int[] {1, 2, 3, 4, 5};
    BinaryTree tree = new BinaryTree(values);
    

    这应该使用值 1 - 5 预先填充二叉树,如下所示:

        1
       / \
      2   3
     / \
    4   5
    

    这可以使用以下类来完成:

    class BinaryTree
    {
        int value;
        BinaryTree left;
        BinaryTree right;
    
        public BinaryTree(int[] values) : this(values, 0) {}
    
        BinaryTree(int[] values, int index)
        {
            Load(this, values, index);
        }
    
        void Load(BinaryTree tree, int[] values, int index)
        {
            this.value = values[index];
            if (index * 2 + 1 < values.Length)
            {
                this.left = new BinaryTree(values, index * 2 + 1);
            }
            if (index * 2 + 2 < values.Length)
            {
                this.right = new BinaryTree(values, index * 2 + 2);
            }
        }
    }
    

    【讨论】:

    • 我可能完全错了,但它不需要某种循环或递归来加载整个数组吗?
    • trick部分,数组中的索引从0开始,所以左边的增量为index*2+1,右边为index*2+2。正常情况下,人们认为在绘制图形时从 1 开始,那么增量会是左索引*2,右索引*2+1
    【解决方案4】:

    如果您正在寻找全面的 BinaryTree 实现的源代码,您可以查看 The C5 Generic Collection Library

    【讨论】:

      【解决方案5】:
        class BstNode
          {
              public int data;
              public BstNode(int data)
              {
                  this.data = data;
              }
              public BstNode left;
              public BstNode right;
          }
          class Program
          {
              public static BstNode Insert(BstNode root, int data)
              {
                  if (root == null) root = new BstNode(data);
                  else if (data <= root.data) root.left = Insert(root.left, data);
                  else if (data > root.data) root.right = Insert(root.right, data);
      
                  return root;
              }
      
      public static void Main(string[] args)
              {
                  // create/insert into BST
                  BstNode Root = null;
                  Root = Insert(Root, 15);
                  Root = Insert(Root, 10);
                  Root = Insert(Root, 20);
                  Root = Insert(Root, 8);
                  Root = Insert(Root, 12);
                  Root = Insert(Root, 17);
                  Root = Insert(Root, 25);
               }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2017-07-01
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 2018-08-04
        • 2011-11-29
        • 2013-12-29
        • 2011-05-08
        相关资源
        最近更新 更多