Java 如何从普通树创建二叉树?

Java 如何从普通树创建二叉树?,java,constructor,tree,binary-tree,Java,Constructor,Tree,Binary Tree,我必须为java中的BinaryTree类解决以下构造函数: BinaryTree(GeneralTree<T> aTree) BinaryTree(GeneralTree-aTree) 此方法应根据常规树(gt)创建二进制树(bt),如下所示: gt中的每个顶点将在bt中表示为一片叶子 如果gt是一个叶,那么bt将是一个与gt值相同的叶 如果gt不是叶,则bt将被构造为空根、左子树(lt)和右子树(lr)。Lt是从gt最古老的子树(最左边的子树)创建的stric二叉树,lr是

我必须为java中的BinaryTree类解决以下构造函数:

BinaryTree(GeneralTree<T> aTree)
BinaryTree(GeneralTree-aTree)
此方法应根据常规树(gt)创建二进制树(bt),如下所示:

gt中的每个顶点将在bt中表示为一片叶子

  • 如果gt是一个叶,那么bt将是一个与gt值相同的叶
  • 如果gt不是叶,则bt将被构造为空根、左子树(lt)和右子树(lr)。Lt是从gt最古老的子树(最左边的子树)创建的stric二叉树,lr是从gt创建的stric二叉树,没有最左边的子树
第一部分很琐碎,但第二部分给我带来了一些麻烦。我已经走了这么远:

public BinaryTree(GeneralTree<T> aTree){
        if (aTree.isLeaf()){
            root= new BinaryNode<T>(aTree.getRootData());
        }else{
            root= new BinaryNode<T>(null); // empty root
            LinkedList<GeneralTree<T>> childs = aTree.getChilds(); // Childs of the GT are implemented as a LinkedList of SubTrees
            child.begin(); //start iteration trough list
            BinaryTree<T> lt = new BinaryTree<T>(childs.element(0)); // first element = left-most child
            this.addLeftChild(lt);
            aTree.DeleteChild(hijos.elemento(0));
            BinaryTree<T> lr = new BinaryTree<T>(aTree);
            this.addRightChild(lr);
        }
    }
公共二叉树(GeneralTree aTree){
if(aTree.isLeaf()){
root=新的二进制节点(aTree.getRootData());
}否则{
root=newbinarynode(null);//根为空
LinkedList childs=aTree.getChilds();//GT的childs被实现为子树的LinkedList
child.begin();//从列表开始迭代
BinaryTree lt=新的BinaryTree(childs.element(0));//第一个元素=最左边的子元素
这个.addLeftChild(lt);
aTree.DeleteChild(hijos.elemento(0));
BinaryTree lr=新的二叉树(aTree);
这是addRightChild(lr);
}
}
这条路对吗?如果没有,你能想出更好的办法来解决这个问题吗?例如,这个解决方案给了我一堆根本没有数据的节点,我不知道这是问题本身还是我的问题


谢谢大家!

问题是大多数树不能有效地简化为二叉树。 阅读您的评论,您完全了解这一点。 以一棵树为例,它的根节点有3个子节点。在不牺牲连通性的情况下,没有直接的方法可以从中生成二叉树。这就是那些空节点的来源。有了它们,一般树的结构得以保留。您可以重建它,删除空节点并从两个子树中重新组装树


我还没有调试你的代码。如果它按照你说的那样做,这是一个很好的解决方案。空节点排序存储常规树的连接信息。它们被允许在那里。

还有另一种广为人知的方法,可以从普通树生成二叉树,而不需要“连接节点”。 最好这样理解此方法:

Node{                Node{
 data;                data;
 first_child;   =>    left;
 next_sibling;        right; 
}                    }
这基本上将常规树的子节点列表表示为链表,每个节点都有一个对其子节点链表的引用。如您所见,这在结构上相当于二叉树

因此,在伪代码中(为了简单起见,省略了边缘情况)

BinaryTree(gtree){
root=BinaryNode(gtree.data,BinaryNode(gtree.children),null);
}
BinaryNode(列出SIB){
BinaryNode(sibs.first.data、BinaryNode(sibs.first.children)、BinaryTree(sibs.rest));
}
BinaryNode(数据、左、右){
数据=数据;
左=左;
右=右;
}

当然,如果你需要你描述的结构,这将是无用的,但一般来说,这是一个从普通树创建二叉树的相当好的方法。

你能详细说明“给我一些麻烦”的意思吗?嘿,马特,谢谢你的回答。“给我一些麻烦”也许不是最好的表达方式,也许吧?我只是想说,我不确定这是否是解决问题的最佳方式。这是我发现的最好的方法,但它有一些问题,例如,二叉树可能会在没有数据的节点上产生一个簇,我认为这可能不是很好?GeneralTree中的节点允许有两个以上的子节点吗?如果是这样,你如何在你的b-树中处理这个问题?理论上,GeneralTree中的一个节点可以有任意数量的子节点。想法是这样的:我得到GT(一个链表)的子对象,我得到第一个(最左边的子对象),并用它创建一个新的BinaryTree()。然后我从树中删除该子级,并用树的其余部分创建一个新的BinaryTree()。理论上,它应该处理每一个孩子,除非我遗漏了什么,那就是v。可能的再次感谢。谢谢你的回复!将空节点视为保留通用树结构的一种方式是有意义的。谢谢你的回答,Mitten!事实上,我需要你有我描述的结构,但这是一个很好的方式去从GT到BT,我会记住它。
BinaryTree(gtree){
    root=BinaryNode(gtree.data,BinaryNode(gtree.children),null);
}

BinaryNode(List<gnode> sibs){
    BinaryNode(sibs.first.data,BinaryNode(sibs.first.children),BinaryTree(sibs.rest));
}

BinaryNode(data,left,right){
    data=data;
    left=left;
    right=right;
}