Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从N元树中随机选择一个节点_Java_Algorithm_Tree_Nodes - Fatal编程技术网

Java 从N元树中随机选择一个节点

Java 从N元树中随机选择一个节点,java,algorithm,tree,nodes,Java,Algorithm,Tree,Nodes,我的节点类: import java.util.ArrayList; public class Tree<T> { private Node<T> root; public Tree(Node<T> root) { this.root = root; } public boolean isEmpty() { return (root == null) ? true : false;

我的节点类:

import java.util.ArrayList;

public class Tree<T> {

    private Node<T> root;

    public Tree(Node<T> root) {
        this.root = root;
    }

    public boolean isEmpty() {
        return (root == null) ? true : false;
    }

    public Node<T> getRoot() {
        return root;
    }

    public void setRoot(Node<T> root) {
        this.root = root;
    }

    public boolean exists(T key) {
        return find(root, key);
    }

    public int getNumberOfNodes() {
        return getNumberOfDescendants(root) + 1;
    }

    public int getNumberOfDescendants(Node<T> node) {
        int n = node.getChildren().size();
        for (Node<T> child : node.getChildren())
            n += getNumberOfDescendants(child);

        return n;

    }

    private boolean find(Node<T> node, T keyNode) {
        boolean res = false;
        if (node.getData().equals(keyNode))
            return true;

        else {
            for (Node<T> child : node.getChildren())
                if (find(child, keyNode))
                    res = true;
        }

        return res;
    }

    private Node<T> findNode(Node<T> node, T keyNode)
    {
        if(node == null)
            return null;
        if(node.getData().equals(keyNode))
            return node;
        else
        {
            Node<T> cnode = null;
            for (Node<T> child : node.getChildren())
                if ((cnode = findNode(child, keyNode)) != null)
                    return cnode;
        }
        return null;         
    } 

    public ArrayList<Node<T>> getPreOrderTraversal() {
        ArrayList<Node<T>> preOrder = new ArrayList<Node<T>>();
        buildPreOrder(root, preOrder);
        return preOrder;
    }

    public ArrayList<Node<T>> getPostOrderTraversal() {
        ArrayList<Node<T>> postOrder = new ArrayList<Node<T>>();
        buildPostOrder(root, postOrder);
        return postOrder;
    }

    private void buildPreOrder(Node<T> node, ArrayList<Node<T>> preOrder) {
        preOrder.add(node);
        for (Node<T> child : node.getChildren()) {
            buildPreOrder(child, preOrder);
        }
    }

    private void buildPostOrder(Node<T> node, ArrayList<Node<T>> postOrder) {
        for (Node<T> child : node.getChildren()) {
            buildPostOrder(child, postOrder);
        }
        postOrder.add(node);
    }

    public ArrayList<Node<T>> getLongestPathFromRootToAnyLeaf() {
        ArrayList<Node<T>> longestPath = null;
        int max = 0;
        for (ArrayList<Node<T>> path : getPathsFromRootToAnyLeaf()) {
            if (path.size() > max) {
                max = path.size();
                longestPath = path;
            }
        }
        return longestPath;
    }

    public int getMaxDepth()
    {
        return getLongestPathFromRootToAnyLeaf().size();
    }

    public ArrayList<ArrayList<Node<T>>> getPathsFromRootToAnyLeaf() {
        ArrayList<ArrayList<Node<T>>> paths = new ArrayList<ArrayList<Node<T>>>();
        ArrayList<Node<T>> currentPath = new ArrayList<Node<T>>();
        getPath(root, currentPath, paths);

        return paths;
    }

    private void getPath(Node<T> node, ArrayList<Node<T>> currentPath,
            ArrayList<ArrayList<Node<T>>> paths) {
        if (currentPath == null)
            return;

        currentPath.add(node);

        if (node.getChildren().size() == 0) {
            // This is a leaf
            paths.add(clone(currentPath));
        }
        for (Node<T> child : node.getChildren())
            getPath(child, currentPath, paths);

        int index = currentPath.indexOf(node);
        for (int i = index; i < currentPath.size(); i++)
            currentPath.remove(index);
    }

    private ArrayList<Node<T>> clone(ArrayList<Node<T>> list) {
        ArrayList<Node<T>> newList = new ArrayList<Node<T>>();
        for (Node<T> node : list)
            newList.add(new Node<T>(node));

        return newList;
    }
}
import java.util.ArrayList;
公共类树{
私有节点根;
公共树(节点根){
this.root=根;
}
公共布尔值为空(){
返回(root==null)?真:假;
}
公共节点getRoot(){
返回根;
}
公共void setRoot(节点根){
this.root=根;
}
存在公共布尔值(T键){
返回find(root,key);
}
public int getNumberOfNodes(){
返回getNumberOfSubstands(根)+1;
}
public int getNumberOfSubstands(节点){
int n=node.getChildren().size();
对于(节点子节点:Node.getChildren())
n+=GetNumberOfSubstands(子代);
返回n;
}
私有布尔查找(节点,T键节点){
布尔res=false;
if(node.getData().equals(keyNode))
返回true;
否则{
对于(节点子节点:Node.getChildren())
if(查找(子节点、键节点))
res=真;
}
返回res;
}
私有节点findNode(节点节点,T键节点)
{
if(node==null)
返回null;
if(node.getData().equals(keyNode))
返回节点;
其他的
{
节点cnode=null;
对于(节点子节点:Node.getChildren())
if((cnode=findNode(子节点,keyNode))!=null)
返回cnode;
}
返回null;
} 
公共阵列列表getPreOrderTraversal(){
ArrayList preOrder=新的ArrayList();
buildPreOrder(根,preOrder);
返回预订单;
}
公共ArrayList getPostOrderTraversal(){
ArrayList postOrder=新的ArrayList();
buildPostOrder(根,postOrder);
邮购退货;
}
私有void buildPreOrder(节点节点,ArrayList preOrder){
添加(节点);
对于(节点子节点:Node.getChildren()){
buildPreOrder(子级,preOrder);
}
}
私有void buildPostOrder(节点,ArrayList postOrder){
对于(节点子节点:Node.getChildren()){
构建postOrder(子级,postOrder);
}
添加(节点);
}
公共阵列列表getLongestPathFromRootToAnyLeaf(){
ArrayList longestPath=null;
int max=0;
for(ArrayList路径:GetPathFromRootToAnyLeaf()){
if(path.size()>max){
max=path.size();
最长路径=路径;
}
}
返回最长路径;
}
public int getMaxDepth()
{
返回getLongestPathFromRootToAnyLeaf().size();
}
public ArrayList getPathsFromRootToAnyLeaf(){
ArrayList路径=新的ArrayList();
ArrayList currentPath=新的ArrayList();
getPath(根、当前路径、路径);
返回路径;
}
私有void getPath(节点节点,ArrayList currentPath,
阵列列表路径){
如果(currentPath==null)
返回;
添加(节点);
if(node.getChildren().size()==0){
//这是一片叶子
添加(克隆(当前路径));
}
对于(节点子节点:Node.getChildren())
getPath(子级、当前路径、路径);
int index=currentPath.indexOf(节点);
for(int i=index;i
我的树类:

import java.util.ArrayList;
import java.util.List;

public class Node<T> {
    private T data;
    private List<Node<T>> children;
    private Node<T> parent;

    public Node(T data) {
        this.data = data;
        this.children = new ArrayList<Node<T>>();
    }

    public Node(Node<T> node) {
        this.data = (T) node.getData();
        children = new ArrayList<Node<T>>();
    }

    public void addChild(Node<T> child) {
        child.setParent(this);
        children.add(child);
    }

    public void addChildAt(int index, Node<T> child) {
        child.setParent(this);
        this.children.add(index, child);
    }

    public void setChildren(List<Node<T>> children) {
        for (Node<T> child : children)
            child.setParent(this);

        this.children = children;
    }

    public void removeChildren() {
        this.children.clear();
    }

    public Node<T> removeChildAt(int index) {
        return children.remove(index);
    }


    public void removeThisIfItsAChild(Node<T> childToBeDeleted)
    {
        List <Node<T>> list = getChildren();
        list.remove(childToBeDeleted);
    }

    public T getData() {
        return this.data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public Node<T> getParent() {
        return this.parent;
    }

    public void setParent(Node<T> parent) {
        this.parent = parent;
    }

    public List<Node<T>> getChildren() {
        return this.children;
    }

    public Node<T> getChildAt(int index) {
        return children.get(index);
    }

    @Override
    public boolean equals(Object obj) {
        if (null == obj)
            return false;

        if (obj instanceof Node) {
            if (((Node<?>) obj).getData().equals(this.data))
                return true;
        }

        return false;
    }

    @Override
    public String toString() {
        return this.data.toString();
    }

}
import java.util.ArrayList;
导入java.util.List;
公共类节点{
私有T数据;
私人名单儿童;
私有节点父节点;
公共节点(T数据){
这个数据=数据;
this.children=new ArrayList();
}
公共节点(节点){
this.data=(T)node.getData();
children=newarraylist();
}
公共void addChild(节点子节点){
child.setParent(this);
添加(child);
}
public void addChildAt(int索引,节点子级){
child.setParent(this);
this.children.add(索引,child);
}
公共子项(列出子项){
用于(节点子节点:子节点)
child.setParent(this);
这个。孩子=孩子;
}
公共无效删除儿童(){
这个.children.clear();
}
公共节点removeChildAt(int索引){
返回子项。删除(索引);
}
public void removethisifitschild(节点childToBeDeleted)
{
List=getChildren();
list.remove(childToBeDeleted);
}
公共T getData(){
返回此.data;
}
公共无效设置数据(T数据){
这个数据=数据;
}
公共节点getParent(){
将此文件返回给父对象;
}
公共void setParent(节点父节点){
this.parent=parent;
}
公共列表getChildren(){
把这个还给孩子们;
}
公共节点getChildAt(int索引){
返回子项。获取(索引);
}
@凌驾
公共布尔等于(对象obj){
if(null==obj)
返回false;
if(节点的obj实例){
if(((节点)obj.getData().equals(this.data))
返回true;
}
返回false;
}
@凌驾
公共字符串toString(){
返回此.data.toString();
}
}
在创建一棵树之后,我将如何从所述树中随机选择一个节点(包括根节点)。从树中选择一个随机节点后,我需要能够删除该节点并用一个新的子树替换它


最好的方法是什么?谢谢。

这将用新节点替换树中的随机节点:

public static void replaceRandom(Tree<T> tree, Node<T> newNode) { 
  // Find a random node
  List<Node<T>> nodeList = tree.getPreOrderTraversal();
  int globalIndex = (int) (Math.random() * nodeList.size());
  Node<T> old = nodeList.get(globalIndex);

  if (old.isRoot()) {
    // If it is the root, we just replace the root.
    tree.setRoot(newNode);
  } else {
    // Otherwise, we need to find the local index to replace it.
    Node<T> parent = old.getParent();
    int localIndex = parent.getChildren().indexOf(old);
    parent.removeChildAt(localIndex);
    parent.addChildAt(localIndex, newNode);
  }
}
publicstaticvoidreplacerandom(树,节点newNode){
//查找随机节点
List nodeList=tree.getPreOrderTraversal