Java:跟踪链接列表中的属性?

时间:2016-01-31 04:11:45

标签: java performance list loops nullpointerexception

这是我为此assignment撰写的方法。它基本上跟踪刺客游戏。

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

这个名单被称为杀戮戒指(暗杀目标的循环链)。例如,如果您有4名球员,分别名为Sally,Matthew,Evan和Christina,可能的配置是:

莎莉 - >马修--->埃文 - >克里斯蒂娜 - >回到莎莉。

kill方法记录了具有给定名字的人的杀戮,将该人从杀戮戒指转移到坟墓场(其中列出了所有已被杀害的人的名字)。

杀戮戒指由AssassinNodes组成,与LinkNodes中的LinkedLists非常相似,只是AssassinNodes有三个字段:人名this.name ),他们的刺客的名字(this.killer)和引用他们的目标的指针(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;
        }
    }
}

2 个答案:

答案 0 :(得分:0)

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

当调用“kill”方法时,在地图中查找AssasinNode,将其删除,如果它具有“previous”和“next”节点,则使它们指向对方。边缘情况是当您只有一个节点时,它是自己的网络和前一个节点。然后,只需将其从地图中删除即可。

答案 1 :(得分:0)

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

在你的情况下发生的情况是,当你试图删除第一个节点时,你正确调整前指针,但你实际上从来没有取消环节点的链接:你只需将它发送到坟墓场,而它的前任节点来自戒指还在指着它。

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

AssassinNode previous = front;

在风格上,我更喜欢先前/当前的步骤被写为

previous = current;
current = current.next;

在前进时通常无需检查'previous == null'。