繁体   English   中英

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

[英]How to push nodes from a Binary Tree into an Array?

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

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

等一下,这是一个二叉搜索树,所以它已经被排序了。

然后,您需要走树。

假设您有以下内容:

   4
 /   \
2      6
 \    /  \
  3  5    9

要插入它,您必须:

给定树根

  • 答:如果树为空,则没有任何要插入的内容。
  • B.如果不为null:
    • 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 =[]

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

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

//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]

我们在右边重复

一片空白? 否,然后在分支上以5插入B,插入6,在分支上以9进行步骤B

//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]

我想到了。 我将公开代码并解释发生了什么。

在公众场合,我列出了一个即将成为数组列表的列表。 然后,我调用toArray helper方法(私有)来设置值。 根目录进入最上层目录,lista进入列表。创建Array并使用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);
        }
    }

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

这里描述的步骤的工作示例

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM