使用TreeMap查找最大元素

时间:2014-11-16 19:27:40

标签: java data-structures heap time-complexity treemap

我正在设计一个前5名击球手的棒球联赛记分牌。我使用TreeMap player_name 用作value,将Player用作key

Map<Player, String> players  = new TreeMap<>(Collections.reverseOrder());

Player课程按照联赛中的得分自然排序 compare(this.leagueRuns, otherPlayer.leagueRuns)

游戏期间

leagueRuns会更新,并且TOP 5 Batsmen记分牌也应相应更改。以下是更新玩家联赛并重新插入TreeMap的代码。更新后,将检索并显示来自Map的TOP 5条目。

 public void updateRuns(String playerName, int runsScored) {

            Iterator<Entry<Player, String>> playersEntries = players.entrySet().iterator();

            Player player = null;
            while (playersEntries.hasNext()) {
                Entry<Player, String> currentPlayer = playersEntries.next();
                if (currentPlayer.getValue().equalsIgnoreCase(playerName)) {
                    player = currentPlayer.getKey();
                }
            }
            players.remove(player);
            player.addRuns(runsScored);
            players.put(player, player.getName());        
 }

一切正常,但我有以下顾虑:

  1. 为了对Player进行排序,我在Key中将其用作TreeMap。但必须遍历整个Map以查找正在更新的Player。因此,时间复杂度从O(1)降低到O(n)。更糟糕的是因为我必须删除Player,更新它并重新插入否则更改将不会生效。因此O(n + logn)。有没有办法按照自然顺序对Player进行排序,也可以在O(1)中搜索。我想重新插入是不可避免的。
  2. 每次为玩家更新leagueRuns时,都必须重新订购整个TreeMap。你认为创造一个单独的TOP 5 Batsmen的最小堆可以解决这个问题,这是一个可行的想法。
  3. 有关设计或改善时间复杂性的任何提示。

1 个答案:

答案 0 :(得分:2)

你应该支持2种结构:

  1. 快速玩家搜索(name =&gt; Player),例如HashMap&lt; String,Player&gt;
  2. 记分板的排序结构(玩家和分数),例如TreeSet中&LT;播放&GT;
  3. 因此更新记分板将为O(log(N)):

    Map<String, Player> players;
    SortedSet<Player> scoreboard;
    
    public void updateRuns(String playerName, int runsScored) {
        Player player = players.get(playerName);
        if (player == null) {
            player = new Player(playerName, runsScored);
        } else {
            scorepoard.remove(player);
            player.addRuns(runsScored);
        }
        scoreboard.add(player);
    }
    

    如果你使Player类不可修改(首选方式),你将获得相同的O(log(N)):

    public void updateRuns(String playerName, int runsScored) {
        Player player = players.remove(playerName);
        if (player == null) {
            player = new Player(playerName, runsScored);
        } else {
            scorepoard.remove(player);
            player = new Player(playerName, player.getRuns() + runsScored);
        }
        players.put(playerName, player);
        scoreboard.add(player);
    }