Java中的BST - 按字符串搜索节点

时间:2012-04-19 16:03:48

标签: java string search insert binary-search-tree

我正在使用具有MovieInfo对象作为键的节点创建二叉搜索树。 MovieInfo对象是具有三个字段的对象:ID,fullName和shortName。二叉搜索树将存储包含IMDB上列出的每部电影的输入文本文件的信息。插入将基于与每个电影随机关联的ID。搜索功能将具有用户输入字符串并拉出对象的其他数据(shortName,ID等)。 现在 - 我遇到的错误是使用findExact方法。 首先,无论我的输入是什么 - 我收到消息“当前节点为空”,这意味着我的起始currentNode始终为null。另一个问题是,我不确定如何确保我的根节点(在树中搜索的第一个currentNode)被正确初始化。我觉得这可能与我的问题有关。 另一个问题可能在于我如何首先插入节点。 作为参考,我在文本输入文件中测试此代码/运行的方式是IndexTester.java。

更新:好的。现在一切都有效。我现在唯一的问题是我的findExact方法似乎改变了MovieInfo类的ID字段。所以我的搜索结果并没有结束。例如,如果我输入:

1568482 2 White Kids with Problems  2 White Kids with Problems
1568487 Disorient   Disorient
1568488 DIY Playgrounds DIY Playgrounds

并搜索“迷失方向”,返回“1568488 Disorient Disorient”(带有“2个有问题的白人小孩”对象的ID)。此外,由于ID已被采用... DIY游乐场无法成功搜索。插入方法有效,但findExact方法给了我一些问题。关于ID可能导致这种变化的任何想法?

MovieInfo类(单独的.java文件) - 无法编辑

public class MovieInfo {
    public String shortName;
    public String fullName;
    static int ID;
    public String key;

    public MovieInfo(int id, String s, String f) {
        ID = id;
        shortName = s;
        fullName = f;
    }
}

BSTIndex.java - 我在其中创建内部BST的类

import java.util.*;
import java.io.*;

public class BSTIndex extends MovieInfo {

    public Node root;
    public class Node{
        public MovieInfo movie;
        public Node left, right;

    public Node(MovieInfo movie)
    {
        this.movie = movie;
        //this.val = val;
        //this.N = N;
        }
    }

    public BSTIndex()
    /**
     * constructor to initialize the internal binary search tree. 
     * The data element should be an object of the type MovieInfo, described above.
     */
    {   
        super(0, "", "");

    }


    public MovieInfo findExact(String key) {
    return findExact(root, key);
}

private MovieInfo findExact(Node x, String key) {
    if (x == null) return null;
    int cmp = key.compareToIgnoreCase(x.movie.fullName);
    if      (cmp < 0) return findExact(x.left, key);
    else if (cmp > 0) return findExact(x.right, key);
    else              return x.movie;
}

    public void insert(MovieInfo data)
    {
        if (data == null) {return; }
        root = insert(root, data);
    }

    public Node insert(Node x, MovieInfo data)
    {   
        if (x == null) return new Node(data);
        int cmp = data.ID - x.movie.ID;
        if (cmp > 0 )       x.right = insert(x.right, data);
        else if (cmp < 0)   x.left = insert(x.left, data);
        else if (cmp == 0)  x.movie = data;
        return x;
    }
}

IndexTester.java

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;


public class IndexTester {

    // Test program
    public static void main( String [ ] args ) throws FileNotFoundException
    {
        BSTIndex t = new BSTIndex( );
        Scanner scan = new Scanner(new FileInputStream(args[0]));
        long start = System.currentTimeMillis();
        int i=0;

        while(scan.hasNext()){
            String line = scan.nextLine();
            String [] fields = line.split("\t");
            int id = Integer.parseInt(fields[0].trim());
            String shortName = fields[1].trim();
            String fullName = fields[2].trim();
            MovieInfo info = new MovieInfo(id, shortName, fullName);

            t.insert(info);
            i++;
            if(i % 10000 == 0){
                System.out.println("Inserted " + i + " records.");
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("Index building complete. Inserted " + i + 
            " records.Elapsed time = " + (end - start )/1000 + " seconds.");

        Scanner input = new Scanner(System.in);

        System.out.println("Enter search string, end in a '*' for 
            prefix search. q to quit");
        while(input.hasNext()){
            String search = input.nextLine().trim();
            if(search.equals("q")) break;
            if(search.indexOf('*')>0){
                //call prefix search. 

                MovieInfo item = t.findPrefix(search);
                if(item==null) System.out.println("Not Found"); 
                else System.out.println(item.ID + " " + item.shortName + " 
                            " + item.fullName);

            }
            else{
                //call exact search, modify to return MovieInfo
                MovieInfo item = t.findExact(search); 
                if(item==null) System.out.println("Not Found");
                else System.out.println(item.ID + " " + item.shortName + " 
                            " + item.fullName);
            }
        }


    }   
} 

1 个答案:

答案 0 :(得分:0)

公共类BSTIndex不应该扩展MovieInfo,最好是MovieInfo应该扩展Node。

好的,所以不能修改MovieInfo,所以我会用数据填充MovieInfo类,并将其设置为扩展Node类的nodevalue。

public class BSTNode extends Node {
    private BSTNode left,right;
    private MovieInfo val;

    public void setVal(MovieInfo val){
        this.val=val;
    }

    public void setLeft(MovieInfo m){
        left=new BSTNode(m);
    }
    public void setRight(MovieInfo m){
        right=new BSTNode(m);
    }
    //override some of the Node methods
}