1

我似乎在将右节点添加到左节点时遇到问题。我有一个预购中列出的输入文件 (.txt)

Fred    1900
2
John    1925
3
Mary    1950
2
Jason   1972
0
Heather 1975
2
Sydney  2002
0
Hailey  2005
0
John    1951
1
Amy 1983
0
Fred    1953
3
Mark    1977
0
Sarah   1979
1
Michael 2005
0
Adam    1982
0
Joan    1927
2
Susan   1949
0
David   1952
1
Fred    1980
0

这是我的节点类:

public class Node {
    public String name;
    public int year;
    //this will help with determining the parent in the insertion process
    public int children;    
    public Node parent;
    public Node left;
    public Node right;


    public Node(String name, int year, int children){
        this.name = name;
        this.year = year;
        this.children = children;
    }
}

假设我的节点已成功创建,我似乎在创建实际树时遇到了问题。

public class FamilyTree {    

    public Node familyTree;

    private Node pivotalNode;
    private Node parent;
    private int children = 0;
    //This method adds a family member to the family tree    
    public void add(Node newNode){
        familyTree = add(familyTree,newNode);
    }
    private Node add(Node familyTree, Node newNode){        
        if(familyTree == null){
            children = newNode.children;
            newNode.parent = parent;
            familyTree = newNode;

        }
        else if(children > 0){
            parent = familyTree;
            familyTree.left = add(familyTree.left, newNode);
            pivotalNode = familyTree.left;
        }
        else if(children == 0){          

            familyTree.right = add(familyTree.right, newNode);
            return pivotalNode;
        }        
        return familyTree;
    }  
} 

结果将显示一棵树,如下所示: 在此处输入图像描述

这是我的主要方法:

public class Operations {

    //Not necessary but it helps me to get more organized. Just want to extract information first.
    public static ArrayList<String> information = new ArrayList<String>();  

    public static void main(String args[]){
        //extract information from file
        getFileContents();

        //Object initialization
        FamilyTree family = new FamilyTree();

        //some useful variables for loop below
        int children =0;
        String[] splitted = null;
        Node member = null;        

        for(int i=0; i<information.size(); i++){
            //Every other line in the text file perform a different operation
            if(i % 2 == 1){
                try{
                    children = Integer.parseInt(information.get(i));
                    member = new Node(splitted[0], Integer.parseInt(splitted[1]), children);
                    family.add(member);
                }
                catch(Exception e){
                    //this determines if the pattern is broken
                    break;
                }
            }
            if(i % 2 == 0){                               
                splitted = information.get(i).split("\\s+");
                //this determines a pattern difference                
                if(splitted.length < 2){
                    break;
                }
            }
        }
        System.out.print("hi");
    }
    //Pretty self explanatory. Read each line of the file and store it into an array. 
    //Not necessary as everything could technically be done at once (insertion), but this keeps me 
    //more organized to put everything together later on 
    public static void getFileContents(){
        try{
            BufferedReader br = new BufferedReader(new FileReader("includes\\assn2in.txt"));            

            String line;
            String info;

            while ((line = br.readLine()) != null) {
                info = line.replaceAll("\\s+", " ");
                information.add(info);               
            }            
            br.close();


        }
        catch(IOException e){
            System.out.println("Error: "+e);
        }
    } 
}

任何帮助将不胜感激。

4

1 回答 1

0

您遇到的一个大问题是您的Node类对二叉树结构进行了建模——也就是说,它包含代表子级leftright成员——但数据本身并不符合这种结构。如果您查看图表,您可以看到一些节点有多达三个子节点(例如 John 1925 和 Fred 1953)。您需要使用 anArrayList而不是leftandright以便您Node可以处理任意数量的孩子:

public class Node {
    public String name;
    public int year;
    //this will help with determining the parent in the insertion process
    public int expectedNumberOfChildren;    
    public Node parent;
    public ArrayList<Node> children;

    public Node(String name, int year, int expectedNumberOfChildren){
        this.name = name;
        this.year = year;
        this.expectedNumberOfChildren = expectedNumberOfChildren;
        this.children = new ArrayList<Node>(expectedNumberOfChildren);
    }
}

至于从数据文件构建树,我将使用Stack具有以下算法(伪代码)的结构:

  • 创建一个空堆栈。
  • 将名为“root”的节点变量初始化为空。
  • 打开数据文件进行读取。
  • 虽然不在文件末尾:
    • 从文件中读取下一个姓名、年份和预期的孩子人数。
    • 根据名称、年份和预期的子节点数创建一个新节点。
    • 如果根节点为空:
      • 将根节点设置为新节点。
      • 将新节点压入堆栈。
    • 否则:
      • 从堆栈中弹出最后一个节点(称为“父节点”)。
      • 将新节点的父节点设置为刚刚从堆栈中弹出的父节点。
      • 将新节点添加到父节点的子节点列表中。
      • 如果父项的子项列表的实际大小小于父项最初从文件中读取的子项的预期数量,则将父项推回堆栈。
      • 如果新节点的预期子节点数大于零,则将其压入堆栈。
  • 关闭文件。

就是这样。当循环结束时,假设输入文件格式正确,“根”节点将指向完全构建的树。(之后不再需要堆栈。)

于 2016-10-29T19:56:03.223 回答