如何将节点从二叉树推入数组?

时间:2019-04-24 15:45:40

标签: java arrays sorting binary-search-tree nodes

我正在努力将二进制搜索树中的值推入数组,但是我也需要对它们进行排序。以下是所需说明。

toArray方法应创建并返回一个数组,该数组包含树中按排序顺序(“按顺序”)的每个元素。该数组的容量应等于其包含的元素数。此方法应利用递归私有帮助器方法toArray(BSTNode,List)生成数组。该数组将需要创建为可比较对象的数组,并转换为E对象的数组。您可以使用Collection的toArray(E [])方法来帮助生成数组。

因此,这是我到目前为止的代码:

 public E[] toArray()
    {
        List<E> lista = new ArrayList<E>();
        toArray(root, lista);
        E[] good = (E[]) lista.toArray();
        return good;
    }
    private void toArray(BSTNode<E> node, List<E> aList)
    {
        if(node.left != null)
        {
            aList.add(node.left.data);
        }
    }

这是其余的参考代码,但是我比任何东西都更专注于toArray方法。我不知道如何将它们排序为数组。请帮忙。

public class BinarySearchTree<E extends Comparable<E>>
{
private BSTNode<E> root; // root of overall tree
private int numElements;

// post: constructs an empty search tree
public BinarySearchTree()
{
    root = null;
}

// post: value added to tree so as to preserve binary search tree
public void add(E value)
{
    root = add(root, value);
}
// post: value added to tree so as to preserve binary search tree
private BSTNode<E> add(BSTNode<E> node, E value)
{
    if (node == null)
    {
        node = new BSTNode<E>(value);
        numElements++;
    }
    else if (node.data.compareTo(value) > 0)
    {
        node.left = add(node.left, value);
    }
    else if (node.data.compareTo(value) < 0)
    {
        node.right = add(node.right, value);
    }
    return node;
}

// post: returns true if tree contains value, returns false otherwise
public boolean contains(E value)
{
    return contains(root, value);
}
// post: returns true if given tree contains value, returns false otherwise
private boolean contains(BSTNode<E> node, E value)
{
    if (node == null)
    {
        return false;
    }
    else
        {
        int compare = value.compareTo(node.data);
        if (compare == 0)
        {
            return true;
        }
        else if (compare < 0)
        {
            return contains(node.left, value);
        }
        else
            {   // compare > 0
            return contains(node.right, value);
        }
    }
}
    public void remove(E value)
    {
        root = remove(root, value);
    }
    private BSTNode<E> remove(BSTNode<E> node, E value)
    {
        if(node == null)
        {
            return null;
        }
        else if(node.data.compareTo(value) < 0)
        {
            node.right = remove(node.right, value);
        }
        else if(node.data.compareTo(value) > 0)
        {
            node.left = remove(node.left, value);
        }
        else
        {
            if(node.right == null)
            {
                numElements--;
                return node.left;// no R child; replace w/ L
            }
            else if(node.left == null)
            {
                numElements--;
                return node.right;   // no L child; replace w/ R
            }
            else
            {
                // both children; replace w/ max from L
                node.data = getMax(node.left);
                node.left = remove(node.left, node.data);
            }
        }
        return node;
    }
    private E getMax(BSTNode<E> node)
    {
        if(node.right == null)
        {
            return node.data;
        }
        else
        {
            return getMax(node.right);
        }
    }
    public void clear()
    {
        root = null;
        numElements--;
    }
    public boolean isEmpty()
    {
        if(numElements == 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    public int size()
    {
        return numElements;
    }
    //My toArray Methods will go here. 
    public Iterator<E> iterator()
    {
        return new Iterator<>(root);
    }
    public static class Iterator<E>
    {
        private Stack<BSTNode<E>> stack;

        public Iterator(BSTNode<E> node)
        {
            this.stack = new Stack<>();
            while (node != null)
            {
                stack.push(node);
                node = node.left;
            }
        }
        public boolean hasNext()
        {
            return !stack.isEmpty();
        }
        public E next()
        {
            BSTNode<E> goodDays = stack.pop();
            E result = goodDays.data;
            if (goodDays.right != null)
            {
                goodDays = goodDays.right;
                while (goodDays != null)
                {
                    stack.push(goodDays);
                    goodDays = goodDays.left;
                }
            }
            return result;
        }
    }
private static class BSTNode<E>
{
    public E data;
    public BSTNode<E> left;
    public BSTNode<E> right;

    public BSTNode(E data)
    {
        this(data, null, null);
    }
    public BSTNode(E data, BSTNode<E> left, BSTNode<E> right)
    {
        this.data = data;
        this.left = left;
        this.right = right;
    }
}
}

3 个答案:

答案 0 :(得分:2)

等等,这是一个二叉搜索树,因此已经排序。

那你需要走树。

鉴于您有类似的内容:

   4
 /   \
2      6
 \    /  \
  3  5    9

要插入它,您必须:

给出树根

  • A。如果树为空,则无需插入任何内容。
  • B。如果不为空:
    • B.1在左侧插入所有内容
    • B.2插入树的根
    • B.3在右侧插入所有内容

如下所示:

void walkAndInsert(tree, array) {
    if (tree == null) {//A
        return
    } else { //B
      walkAndInsert(tree.left) //B.1
      array.add(tree.root) //B.2
      walkAndInsert(tree.right) //B.3
    }
}    

因此在数组上应用以下步骤:

树是否为空?否,然后执行步骤#B(插入所有左侧,根目录和所有右侧)

//B
tree = 
   4
 /   \
2      6
 \    /  \
  3  5    9

array =[]

我们进入左侧分支并重复该过程(步骤#B.1,在所有左侧插入):

树是否为空?否,然后执行#B

//B.1
tree = 
2      
 \      
  3     

array =[]

由于左分支为null,因此下一次执行将如下所示:

树是否为空?是的,然后返回

//A
tree = 

array = []

这将结束步骤B.1,我们现在可以进入步骤B.2,插入root

//B.2
tree = 
2      
 \      
  3     

array =[2]

在步骤B.3之后,全部从右插入

树是否为空?不(那里有3个),

//B.3
tree =      
  3     

array =[2]

然后在这棵树上执行#B.1

树是空的吗?是的,到此B.1结束了。

//A
tree =      

array =[2]

现在在B.2中,我们插入此根目录

树是否为空?否(那里有3个),

//B.2
tree =      
  3     

array =[2,3]

最后我们进入B.3,从右侧全部插入

但是那里什么都没有,所以我们只返回

 //A
tree =      

array =[2,3]

这完成了我们最初的树的左分支。

因此,在初始树上完成B.1之后,我们执行B.2,数据如下:

// B.2 on the initial tree
tree = 
   4
 /   \
2      6
 \    /  \
  3  5    9

array =[2,3,4]

我们在右侧重复

是否为空?否,然后在分支上的B上添加5,插入6,然后在分支上的B上添加9

//B.3
tree = 
    6
   /  \
  5    9

array =[2,3,4]

// B.1
tree = 
    5

array =[2,3,4]

// A
tree = 


array =[2,3,4]

// B.2
tree = 
    5

array =[2,3,4,5]

// B.2
tree = 
    6
   /  \
  5    9

array =[2,3,4,5,6]

// B.3
tree = 
    9

array =[2,3,4,5,6]

// A
tree = 


array =[2,3,4,5,6]

// B.2
tree = 
    9

array =[2,3,4,5,6,9]

答案 1 :(得分:1)

我知道了。我将公开代码并解释发生了什么。

在公众场合,我列出了一个即将成为数组列表的列表。 然后,我调用toArray helper方法(私有)来设置值。根目录用于顶层目录,lista用于目录列表。 之后制作数组并使用numElements设置大小。可比性在那儿,因为在我的代码的最顶端,这就是它的扩展。 然后将该数组放入lista中。 最后返回它。

 public E[] toArray()
    {
        List<E> lista = new ArrayList<E>();
        toArray(root, lista);
        E[] arr = (E[]) new Comparable[numElements];
        lista.toArray(arr);
        return arr;
    }

我私下进行一些递归。 只要节点不为空(null),数组将连续搜索左节点,直到没有左节点为止(左),因此将其添加到数组中。 然后添加正确的。

 private void toArray(BSTNode<E> node, List<E> aList)
    {
        if(node != null)
        {
            toArray(node.left, aList);
            aList.add(node.data);
            toArray(node.right, aList);
        }
    }

很抱歉,如果这很难理解,我不是最擅长解释事物的人,但这对我有用。

答案 2 :(得分:1)

here

中描述的步骤的工作示例
import java.util.*;
import java.lang.reflect.Array;
import static java.lang.System.out;

class Tree<E extends Comparable<E>> {

    E root;
    Tree<E> left;
    Tree<E> right;

    void insert(E element) {
        if (this.root == null) {
            this.root = element;
            this.left = new Tree<E>();
            this.right = new Tree<E>();
        } else if (element.compareTo(this.root) < 0 ) {
            left.insert(element);
        } else {
            right.insert(element);
        }
    }

    E[] toArray() {
      List<E> a = new ArrayList<>();
      toArray(this, a);
      @SuppressWarnings("unchecked")
      final E[] r = a.toArray((E[]) Array.newInstance(a.get(0).getClass(), a.size()));
      return r;
    }

    // instance method just to retain the generic type E
    private void toArray(Tree<E> t, List<E> list) {
        if (t == null || t.root == null) {
            return;
        } else {
            toArray(t.left, list);
            list.add(t.root);
            toArray(t.right, list);
        }
    }

    public static void main(String ... args) {
        Tree<String> t = new Tree<>();
        t.insert("hola");
        t.insert("adios");
        t.insert("fuimonos");

        System.out.println(Arrays.toString(t.toArray()));
    }
}