当前位置: 首页 > 知识库问答 >
问题:

Java中一种完全二叉搜索树的层次顺序插入

池俊茂
2023-03-14

我们有一个任务需要编码:

>

  • 二叉搜索树
  • 树必须是完整的,而不是完美的(这意味着不在最底层或次底层的所有节点都应该有两个子节点,而最底层的节点应该尽可能靠左)
  • 我们需要按级别顺序插入树
  • 因此,如果我有一个包含元素{0,1,2,3,4,5,6,7}的数组,应该是4,左边是2,1,3,0,右边是6,5,7

    插入的级别顺序为:4,2,6,1,3,5,7,0

    只是取数组的中间并将其作为root是行不通的。如果您得到一个由1到9个元素组成的数组,那么您将有4个元素作为根(java中的int值,double将是4.5),您将有5个元素在右侧,4个元素在左侧。这不是一棵完整的树。甚至不是一棵完美的树。

    我的代码只能在左或右插入,这取决于它是否大于或小于根,没有级别顺序插入。anytypex参数是要插入的值,而binarynodet是我们在树中的当前节点(这是我们在需要向左或向右插入新值时进行比较的方式)

    private BinaryNode<AnyType> insert( AnyType x, BinaryNode<AnyType> t )
    {
        if( t == null )
            return new BinaryNode<>( x, null, null );
    
        int compareResult = x.compareTo( t.element );
    
        if( compareResult < 0 )
            t.left = insert( x, t.left );
        else if( compareResult > 0 )
            t.right = insert( x, t.right );
        else
            ;  // Duplicate; do nothing
        return t;
    }
    

    如何才能以级别顺序插入,并且仍然保持一个二叉搜索树?我应该使用某种形式的递归吗?

    我的整个计划

    import java.nio.BufferUnderflowException;
    import java.util.*;
    
    import static java.lang.Math.pow;
    
    /**
     * Implements an unbalanced binary search tree.
     * Note that all "matching" is based on the compareTo method.
     * @author Mark Allen Weiss
     */
    public class BinarySearchTree<AnyType extends Comparable<? super AnyType>>
    {
        /**
         * Construct the tree.
         */
        public BinarySearchTree( )
        {
            root = null;
        }
    
        /**
         * Insert into the tree; duplicates are ignored.
         * @param x the item to insert.
         */
        public void insert( AnyType x )
        {
            root = insert( x, root );
        }
    
        /**
         * Test if the tree is logically empty.
         * @return true if empty, false otherwise.
         */
        public boolean isEmpty( )
        {
            return root == null;
        }
    
        /**
         * Print the tree contents in sorted order.
         */
        public void printTree( )
        {
            if( isEmpty( ) )
                System.out.println( "Empty tree" );
            else
                printTree( root );
        }
    
        /**
         * Internal method to insert into a subtree.
         * @param x the item to insert.
         * @param t the node that roots the subtree.
         * @return the new root of the subtree.
         */
        private BinaryNode<AnyType> insert( AnyType x, BinaryNode<AnyType> t )
        {
            if( t == null )
                return new BinaryNode<>( x, null, null );
    
            int compareResult = x.compareTo( t.element );
    
            if( compareResult < 0 )
                t.left = insert( x, t.left );
            else if( compareResult > 0 )
                t.right = insert( x, t.right );
            else
                ;  // Duplicate; do nothing
            return t;
        }
    
        /**
         * Internal method to print a subtree in sorted order.
         * @param t the node that roots the subtree.
         */
        private void printTree( BinaryNode<AnyType> t )
        {
            if( t != null )
            {
                printTree( t.left );
                System.out.println( t.element );
                printTree( t.right );
            }
        }
    
        /**
         * Internal method to compute height of a subtree.
         * @param t the node that roots the subtree.
         */
        private int height( BinaryNode<AnyType> t )
        {
            if( t == null )
                return -1;
            else
                return 1 + Math.max( height( t.left ), height( t.right ) );    
        }
    
        // Basic node stored in unbalanced binary search trees
        private static class BinaryNode<AnyType>
        {
                // Constructors
            BinaryNode( AnyType theElement )
            {
                this( theElement, null, null );
            }
    
            BinaryNode( AnyType theElement, BinaryNode<AnyType> lt, BinaryNode<AnyType> rt )
            {
                element  = theElement;
                left     = lt;
                right    = rt;
            }
    
            AnyType element;            // The data in the node
            BinaryNode<AnyType> left;   // Left child
            BinaryNode<AnyType> right;  // Right child
        }
    
          /** The tree root. */
        private BinaryNode<AnyType> root;
    
            // Test program
        public static void main( String [ ] args )
        {
            BinarySearchTree<Integer> t = new BinarySearchTree<>( );
    
            t.insert(2);
            t.insert(1);
            t.insert(3);
            t.printTree();
        }
    }
    
  • 共有1个答案

    葛驰
    2023-03-14

    完整的BST部分花了一点时间来理清它到底是什么。您的需求还需要订单级别的插入。我不能说这做了“插入”,但它建立了秩序级别的BST。

    必须首先对输入列表进行排序。

    构建顺序级别是通过以下方式完成的:取根并将其添加到BST中,然后将左列表拆分为左列表和右列表,将它们添加到列表列表中,然后处理列表列表。每一轮对列表的拆分和添加都是一个级别的插入。

    好像管用。

    public class Node<T extends Comparable<T>> {
        protected Node<T> left;
        protected Node<T> right;
        protected T data;   
    }
    
    public class BTree<T extends Comparable<T>> {
        private Node<T> root = new Node<>();
        public void addData(T data) {
            Node<T> parent = root;
            while (parent.data != null ) {
                if ( data.compareTo( parent.data ) > 0 ) {
                    if ( parent.right == null ) 
                        parent.right = new Node<>();
                    parent = parent.right;
                } else {
                    if ( parent.left == null ) 
                        parent.left = new Node<>();
                    parent = parent.left;
                }
            }
            parent.data = data;
        }
    }
    
    private void run() {
        for ( int i = 2; i < 65; ++i ) {
            List<Integer> intList = IntStream.range(1, i).boxed().collect(Collectors.toList());
            BTree<Integer> bTree = new BTree<>();
            List<List<Integer>> splitLists = new ArrayList<>();
            splitLists.add(intList);
            while (splitLists.size() > 0 ) {
                List<List<Integer>> tSplitLists = new ArrayList<>();
                for ( List<Integer> tIntList: splitLists) {
                    int length = tIntList.size();
                    // compute starting point
                    int mid = calcMid(length);      // length/2 ; //+ calcOffset(length);
                    bTree.addData(tIntList.get(mid));
                    if ( mid - 0 > 0)
                        tSplitLists.add(tIntList.subList(0, mid));
                    if ( length - (mid+1) > 0)
                        tSplitLists.add(tIntList.subList(mid+1, length));
                }
                splitLists = tSplitLists;
            }
            bTree.printNode();
        }
    }
    private int calcMid(int length) {
        if ( length <= 4 )
            return length / 2;
        int levelSize = 1;
        int total = 1;
        while ( total < length ) {
            levelSize *= 2;
            total += levelSize;
        }
        int excess = length - (total - levelSize);
        int minMid = (total - levelSize + 1) / 2;
        if ( excess <= levelSize / 2 ) {
            return minMid + (excess - 1); 
        } else {
            int midExcess = levelSize/2; 
            return minMid + (midExcess - 1);
        }
    
    }
    

    查看如何打印二叉树图?用于打印二叉树的代码

    ps>我相信你可以通过清除和复制列表而不是每次都创建新的列表来使它变得更好。

    1 
    
     2   
    /   
    1   
    
     2   
    / \ 
    1 3
    
       3       
      / \   
     /   \  
     2   4   
    /       
    1
    
     类似资料:
    • 我已经为我的二叉搜索树做了4次不同的遍历。我被困在最后一个,这是水平顺序遍历,我不能得到,似乎找到如何做它正确。 主要的问题是我不知道如何一次只搜索一个层次,我只知道如何搜索整个左或整个右子树。

    • 我想对二叉树执行级别顺序遍历。因此,对于给定的树,说: 产出将是: 我知道我可以使用某种队列,但在C中递归地实现这一点的算法是什么?感谢您的帮助。

    • 二叉搜索树(BST)和二叉树(BT)中的插入有什么区别?我知道,在BST中,您将新节点的值与根进行比较,如果较小,则添加到其左侧,如果较大,则将其添加到根的右侧。BT的程序是否相同?如果没有,插入和移除的步骤是什么?

    • //执行顺序遍历的递归方法

    • 我搜索了一下,但没有找到这个问题的答案... 我构建了一个非二叉树,因此每个节点可以有任意数量的子节点(我认为称为n元树) 为了有助于搜索,我在构建树的时候给了每个节点一个编号,这样每个节点的子节点会更大,它右边的所有节点也会更大。 像这样的东西: 这样我就有更多的时间进行搜索 当我想插入节点时,问题就来了。如果我想在除了结尾以外的任何地方插入节点,这个模型就不起作用了。 我想了几种方法可以做到这

    • 我正在研究数据结构,我遇到了一个难题。目标是根据数组元素的值将数组元素插入到二叉搜索树中,即(主树的根节点为数组[0],左子树的根_node小于父节点,右子树的根节点大于父节点)。这将递归进行,直到所有数组元素都插入BST。 我实现了两个类: 这表示具有属性的节点(数据,左,右): 是BST的私有方法,它执行将节点插入树的实际工作。我将其与分开,因为需要使用RSpec评估的预期解决方案。 然后,我