【问题标题】:Java: Keeping track of properties in a Linked List?Java:跟踪链接列表中的属性?
【发布时间】:2016-05-08 16:57:02
【问题描述】:

这是我为assignment 编写的一种方法。它本质上是跟踪刺客游戏。

在刺客游戏中,每个人都有一个目标,但他们不知道自己的目标是谁。游戏的目标是在活着的同时“杀死”你的目标。我正在编写一个类,它跟踪谁和他们各自的目标的目标列表,同时如果有人被杀,还处理对列表的更改。

这个列表被称为杀戮环(暗杀目标的循环链)。例如,如果您有 4 名玩家,分别名为 Sally、Matthew、Evan 和 Christina,一种可能的配置是:

Sally --> Matthew ---> Evan --> Christina --> 回到 Sally。

kill 方法记录给定名字的人被杀,将人从杀戮环转移到墓地(其中列出了所有被杀的人的名字)。

杀戮环由AssassinNodes组成,很像LinkedLists中的LinkNodes,只是AssassinNodes有三个字段:人名(this.name),刺客姓名(@987654328) @) 和一个引用其目标的指针 (this.next)。

如果您需要有关AssassinNode 的更多详细信息,请参阅上面列出的分配规范。

如果没有NullPointerException 或彻底的低效率,我很难跟踪杀手的名字。我已经解决了中间案例(链接列表的中间)(我认为),但我在前后案例方面遇到了麻烦。

如果您需要更多信息,请告诉我。

public void kill(String name) {
    if (gameOver()) {
        throw new IllegalStateException("The game is now over.");
    } else if (!killRingContains(name)) {
        throw new IllegalArgumentException("This person is not listed in the kill ring."); 
    }
    AssassinNode previous = null;
    AssassinNode current = front;        
    while (current != null) {
        if (name.equalsIgnoreCase(current.name)) {
            if (current.equals(front)) {
                front = front.next;
            } else if (current.next == null) {
                previous.next = null;
            } else {
                previous.next = current.next;
                current.killer = previous.name;
            }

            if (graveyard == null) {
                graveyard = current;
                graveyard.next = null;
            } else {
                current.next = graveyard;
                graveyard = current;
            }
           return;
        } else {
            if (previous == null) {
                previous = front;
            } else {
                previous = previous.next;
            }
            current.killer = previous.name; //added
            current = current.next;
        }
    }
}

【问题讨论】:

  • 我会递归地执行此操作。找到要杀死的人,将其送到墓地,并在堆栈展开时重建列表。

标签: java performance list loops nullpointerexception


【解决方案1】:

如果您只想知道谁还活着而不需要遍历列表,您应该使用 Map (Javadoc) (Examples)。地图允许您按名称(键)存储对象并快速检索它。存储的对象应该是您的 AssasinNode,而 AssasinNode 又会保留对下一个(和上一个)节点的引用。

当调用“kill”方法时,在地图中寻找你的AssasinNode,将其移除,如果它有“previous”和“next”节点,让它们互相指向。边缘情况是当你只有一个节点时,它本身就是它自己的网络和前一个节点。然后,只需将其从地图中移除,什么都不做。

【讨论】:

    【解决方案2】:

    在这种情况下,我发现绘制我的数据结构图并在这些图上逐步重放我的代码很有用。

    在您的情况下发生的情况是,当您尝试删除第一个节点时,您正确调整了前指针,但您从未真正取消该节点与环的链接:您只是将其发送到墓地,而它的前任节点从ring 仍然指向它。

    请记住,您的数据结构是一个环:它没有正面或背面(这也意味着 .next 永远不会为空),因此在删除节点期间“front”点的位置无关紧要 - 您只需要之后将其调整为幸存的节点之一。提示:

    AssassinNode previous = front;
    

    在风格上,我更喜欢将之前/当前的步骤写成

    previous = current;
    current = current.next;
    

    前进时通常不需要检查'previous == null'。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-04
      • 1970-01-01
      • 1970-01-01
      • 2013-05-03
      • 1970-01-01
      相关资源
      最近更新 更多