Java 随机化文本文件以避免不平衡的树

Java 随机化文本文件以避免不平衡的树,java,file-io,binary-search-tree,Java,File Io,Binary Search Tree,目前,我有一个从文本文件中读取的电影列表。以下是一个例子: Forrest Gump/1994/PG-13/142/8.8/Tom Hanks Star Wars/1977/PG/121/8.7/Mark Hamill,Carrie Fisher,Harrison Ford Jaws/1975/PG/124/8.1/ 有人告诉我,在将文本添加到二叉搜索树之前,我应该将文本随机化,以避免出现不平衡的树,这正是我试图实现的。我没有问题阅读文件,我只是需要帮助我找出如何随机文本。我最初的想法是将它存

目前,我有一个从文本文件中读取的电影列表。以下是一个例子:

Forrest Gump/1994/PG-13/142/8.8/Tom Hanks
Star Wars/1977/PG/121/8.7/Mark Hamill,Carrie Fisher,Harrison Ford
Jaws/1975/PG/124/8.1/
有人告诉我,在将文本添加到二叉搜索树之前,我应该将文本随机化,以避免出现不平衡的树,这正是我试图实现的。我没有问题阅读文件,我只是需要帮助我找出如何随机文本。我最初的想法是将它存储到和
ArrayList
中,然后随机填充它,但我想不出具体的实现方法。 下面是我从文本文件中读取的内容:

try{
        Scanner read = new Scanner( new File("movies.txt") );
        do{
            ArrayList<String> actorList = new ArrayList<String>();
            String line = read.nextLine();
            String [] tokens = line.split("/");
            if ( tokens.length == 6 ){
                actorList.addAll( Arrays.asList( tokens[5].split(",") ) );
            }
            // BEFORE ADDING TO TREE I WANT TO RANDOMIZE HERE
            tree.add( new Movie(tokens[0], Integer.parseInt(tokens[1]), tokens[2], Integer.parseInt(tokens[3]), 
                    Double.parseDouble(tokens[4]), actorList ));
        }while( read.hasNext() );
        read.close();
    }catch( FileNotFoundException fnf ){
        System.out.println("File not found.");
    }
要“随机化”您的
列表,请使用
Collections.shuffle()

List movies=new ArrayList();
做{
//…电影`
添加(新电影(…);
}while(read.hasNext());
收藏。洗牌(电影);//洗牌
对于(moviem:movies){//填充树
树。添加(m);
}

这不会使您的树完全平衡,但至少会使树在初始数据集有序的情况下成为链接列表。免责声明:

OP要求搜索所有具有特定评级的电影,这可能会对他有所帮助。根据他的评论
如果您能查看一下这一点以及我在BST中的搜索,看看为什么我在按评级搜索时没有得到所有电影的输出,我将不胜感激。

由于您的树似乎正在使用电影名称作为键,并且您希望根据分级进行搜索,所以您需要反向搜索完整的树。但是,这可能会破坏我们使用
BST
获得对数搜索功能的目的。完整的搜索可以写为:

private Movie searchBasedOnRating(String rating, Node currentNode)
{  
    Node result = null
    if (currentNode == null)
        return null;
    Movie movie = (Movie) currentNode.getData();
    if (movie.getRating().equals(rating)) 
        return movie ;
    if (currentNode.getLeft() != null)
        result = searchBasedOnRating(rating,currentNode.getLeft());
    if (result == null)
        result = searchBasedOnRating(rating,currentNode.getRight());
    return result;
}

你可以根据你的要求修改它,但它应该给你一个高层次的想法。您需要从
根节点开始搜索完整的树。

随机化将如何帮助您避免不平衡的BST?可能是个愚蠢的问题,但请回答。最好让你的树自我平衡。如果您使用Java SE
TreeSet
TreeMap
作为基础,它已经是自平衡的了。为什么不使用
AVL
RedBlackTree
。实际上Java在内部使用
RedBlackTree
本身。@JCCS洗牌或随机化数据对您没有帮助。你需要先了解你的问题。这只是一个建议。问题不在于您的实现本身,常规的
BST
不是自平衡的,并且经常会导致树倾斜。如果你想实现一个完全平衡的树,那么你应该自我平衡
BST
,例如
AVLTree
RedBlackTree
。这有助于保持BST的不平衡吗?@akhil\u mittal如果OP的
不是自我平衡的,洗牌不会使它完全平衡,但是,如果对初始数据集进行排序,至少可以避免树变成链表。是的,但它仍然有可能被扭曲。@akhil_mittal肯定。我不是说完全和适当的平衡。@SashaSalauyou感谢洗牌的目的是确保完全避免得到
LinkedList
类型树。现在我知道这是一个不同的问题,但最初我认为我的树不平衡的原因是因为我刚刚发布的代码有一个问题,我在那里搜索一部电影的评级。如果您能在
BST
中查看我的
search
,看看为什么我在按分级搜索时没有得到所有电影的输出,我将不胜感激。但是,谢谢,这正是我要找的。我会返回
列表
,目的是提供一个如何根据评级搜索电影的想法。OP可以修改代码以满足要求。
    System.out.println("Select a rating: ");
    System.out.println("1. G");
    System.out.println("2. PG");
    System.out.println("3. PG-13");
    System.out.println("4. R");
    switch ( checkForMenu(1,4) ){

    case 1: rating = "G";
            break;
    case 2: rating = "PG";
            break;
    case 3: rating = "PG-13";
            break;
    case 4: rating = "R";
            break;
    }
    Movie temp = new Movie( "Unknown", 0, rating, 0, 0.0, null );
    Node leftMost = tree.search(temp);
    if( leftMost != null ){
           while(leftMost != null && temp.compareTo( leftMost.getData() ) == 0){
                System.out.println(leftMost.getData());
                leftMost = leftMost.getRight();
           }
    }
List<Movie> movies = new ArrayList<>();
do {    
    //...                         // populate `movies`
    movies.add(new Movie(....)); 
} while (read.hasNext());

Collections.shuffle(movies);      // shuffle
for (Movie m : movies) {          // populate the tree
   tree.add(m);
}
private Movie searchBasedOnRating(String rating, Node currentNode)
{  
    Node result = null
    if (currentNode == null)
        return null;
    Movie movie = (Movie) currentNode.getData();
    if (movie.getRating().equals(rating)) 
        return movie ;
    if (currentNode.getLeft() != null)
        result = searchBasedOnRating(rating,currentNode.getLeft());
    if (result == null)
        result = searchBasedOnRating(rating,currentNode.getRight());
    return result;
}