删除链接列表中的元素

时间:2018-06-25 21:15:11

标签: java linked-list

再次寻求帮助,因为我的教授似乎在解释事情上做得很糟糕(假设我们对Java编程了解得太多,而实际上,这是我们大多数人都在学习的第一个Java类)。

不是要找人为我编写代码,而是要找人让我知道我是否在正确的轨道上,并指导我朝正确的方向发展。我真的很想学习这些东西,而不是一味地喂它,但是教授却很难做到这一点,所以我在这里寻求帮助。

问题是获取一个LinkedList并创建一个函数以删除该列表中的第k个元素。我已经弄清楚了如果k == 0时如何删除第一项,但是我迷失了如何在循环中访问“ k”的适当元素。这是我到目前为止的内容:

public class MyLinked {
  static class Node {
    public Node(double item, Node next) {
      this.item = item;
      this.next = next;
    }

    public double item;
    public Node next;
  }

  int N;
  Node first;
  // delete the kth element (where k is between 0 and N-1 inclusive)
  public void delete(int k) {
    if (k < 0 || k >= N) throw new IllegalArgumentException();
    {
      if (k == 0) {
        remove(first.item);
      } else if (k > 0) {
        kElem = LinkedList.get();
        remove(kElem);
      }
    }
  }
}

我正在尝试为.get函数分配一个变量,但是我在那肯定是错误的,但是还不确定如何去做。我知道我需要获取第k个元素的值并将其删除。

我还知道,此后,我需要调整LinkedList中的指针以填补我删除的元素所在的空白。

谢谢。

3 个答案:

答案 0 :(得分:4)

您的链接列表如下:

Link-List-Delete-Operation

在此图像上,上一个是要删除的对象前面的对象。 Cur是您要删除的对象。

循环播放,直到下一个指针指向要删除的对象为止。之后,将prev的下一个指针设置为该对象,该指针紧接在cur之后(cur是要删除的对象)。

用伪代码看起来像这样:

prev = head;
while(prev.next != cur) {
  prev = prev.next
}

此步骤之后,上一个位置正确。

您可以看到,该算法适用于所有情况,除了取下头部外。您可以检查是否要卸下云台并使用其他算法,或者是否使用虚拟节点。使用虚拟节点作为头部,使用虚拟节点作为尾部(此处未显示,但在双链表中使用)。该虚拟节点称为哨兵。您将永远不会删除该标记,但是您的算法无需额外检查即可工作,因为您将删除> 0的元素。

来源: https://www.cs.cmu.edu/~adamchik/15-121/lectures/Linked%20Lists/linked%20lists.html

在评论中,我看到了有关干净代码的讨论。如果您正在学习简洁的代码,将会看到,如果变量表达了它们的目的,那么很多算法将更易于理解。例如,N应该是大小。但是在不同的上下文中,它可能是缓存的元素上限。关于此主题的一本好书是:清洁体系结构:软件结构和设计的工匠指南(Robert C. Martin系列)

您认为更容易理解的内容

int[][] a = new int[100][200];
for(int i = 0; i < a.length) {
  for(int j = 0; j < a[i].length) {
    a[i][j] = i*j;
  }
 }

或者这个:

 int[][] productOfRowColumns = new int[100][200];
 for(int row = 0; i < productOfRowColumns.length) {
  for(int column = 0; j < productOfRowColumns[row].length) {
    productOfRowColumns[row][column] = row*column;
  }
 }

答案 1 :(得分:2)

首先转到k-1元素。设置element.next = element.next.next。这样就可以跳过要删除的元素。

例外:当k = 0(head元素)时,只需设置head = head.next。

(可选)您可以为已删除元素设置next = null(当您使用k-1个元素时,在设置element.next = element.next.next之前先删除delete = element.next。然后说出delete.next = null即可清除它的下一个指针。


还有第二种常见的方式,您可以转到第k个元素,但始终将前一个(k-1)元素保存在变量中。在性能方面,情况更糟,因为在每个步骤中都要更新2个变量。它可能更直观。检查该视频:https://www.youtube.com/watch?v=2RwWsHePdr8(希望SO允许yt链接)


顺便说一句,您的

  static class Node {
    public Node(double item, Node next) {
      this.item = item;
      this.next = next;
    }

    public double item;
    public Node next;
  }

  int N;
  Node first;

是列表的实现。 LinkedList是java提供的实现。 https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html。您不能将它们混合。


提示:

  • 别忘了减小列表的大小(N-;)
  • 您可以使用“节点current = head; for(int i = 0; i
  • 我所说的“头”是您的“第一”。这是列表的第一个元素。

答案 2 :(得分:1)

“ get”方法无法执行您想要的操作。您将需要编写代码以迭代到位置k-1并切换指针,如您所说:-

例如列表1-> 2-> 3-> 4,k = 2

使用下一个指针向上迭代2,将下一个指针指向4。您无需执行其他任何操作(删除等)