如何删除链表中的第一个元素?

时间:2015-10-23 03:05:13

标签: java linked-list

我正在尝试编写一个函数delete(),它接受一个链表并从列表中删除Kth元素。我的代码如下。

public void delete(int k){
  Node current = head;
  for (int i = 0; i < k; i++){
      if(current == null || current.next == null){ //check if list is empty or k is out of bounds

          throw new IndexOutOfBoundsException();
          }
      else 
      {
          current = current.next; // Move pointer to k position
      }
  }
  remove(current.item);
  N--;  
  }

public void remove(E e) {
if (e == null)
  throw new NullPointerException();

// (*) special case (2/one node with e)
if (head != null && head.item.equals(e)) {
  head = null;
  N--;
}
else { // (*) general case (3) -- this also covers the case for empty list
  Node temp;
  // Step 1: bring temp to one node before the node with e.
  for (temp = head; temp != null && !temp.next.item.equals(e);
       temp = temp.next) {} // empty body
  // Step 2: if temp is still in the list, then remove
  if (temp != null) {
    temp.next = temp.next.next;
    --N;
  }
}

}

到目前为止,当我在main中运行lst1.delete(1)lst1.delete(2)等命令时,我的代码按预期工作。但是,当我运行lst1.delete(0)时,它会删除整个链表。我无法弄清楚为什么lst1.delete(0)正在删除整个链表,但我认为这与for循环有关。 for循环循环直到小于k。如果我传入0,那么它可能正在删除头部入口点,即删除整个列表?

我的问题是,有人可以告诉我如何更改我的代码,这样当我运行lst1.delete(0)时,它只删除链表中的第一个元素,而不是整个链表?

5 个答案:

答案 0 :(得分:0)

这应该可以解决您的问题。 你正在设置

head = null; 

如果要移除的项目是头部,但您应该做的是,

if(head.next() != null) {
    head = head.next();
}
else {

    head = null;
}

除非head是列表中唯一的项目,否则这将指向head + 1项目。在这种情况下,我们应该将头设置为null。

public void delete(int k) {

    Node current = head;

    for (int i = 0; i < k; i++){

        if(current == null || current.next == null) { //check if list is empty or k is out of bounds

            throw new IndexOutOfBoundsException();
        }
        else {

            current = current.next; // Move pointer to k position
        }
    }

    remove(current.item);

    N--;  
}

public void remove(E e) {

    if (e == null) {

        throw new NullPointerException();
    }

    // (*) special case (2/one node with e)
    if (head != null && head.item.equals(e)) {

        //Your issue was here
        if(head.next() != null) {

            head = head.next();
        }
        else {

            head = null;
        }

        N--;
    }
    else { // (*) general case (3) -- this also covers the case for empty list

        Node temp;

        // Step 1: bring temp to one node before the node with e.
        for (temp = head; temp != null && !temp.next.item.equals(e);

            temp = temp.next) {} // empty body

            // Step 2: if temp is still in the list, then remove
            if (temp != null) {

                temp.next = temp.next.next;
                    --N;
            }
        }
    }
}

答案 1 :(得分:0)

你的问题在这里

if (head != null && head.item.equals(e)) {
     head = null;
     N--;
}

如果您使用lst1.delete(0),则head.item.equals(e)会在head传递给remove()时变为真。然后删除了整个链接。

一个解决方案是

 if (head != null && head.item.equals(e)&&head.next==null) {
     head = null;
     N--;
}

此处额外检查head.next==null确保链表中只有一个元素。

答案 2 :(得分:0)

1)删除(0)。删除永远不会进入循环因为我小于k是真的直接。所以你删除head.item。 2)然后删除特殊情况2设置head = null。

那2个错误。没有冒犯,但你的代码是一团糟。坐下来用图表再次尝试从头开始解开它。除了如何尽早放弃编程问题之外,其他任何人都会教你什么。

答案 3 :(得分:0)

这是因为当k = 0时,永远不会输入循环。因此,current未更新为指向正确的。{/ p>

答案 4 :(得分:0)

我想出了另一个甚至不调用remove方法的方法。因为我不是最初编写remove方法的人,所以我更喜欢下面的代码而不是其他代码,因为只要方法调用它就会保留在自己的代码中。

public void delete(int k){
  //instance variable
  Node current = head;

  if(current == null || current.next == null){ //check if list is empty

      throw new NullPointerException();
      }

  if (k < 0 || k >= size()){                  // check if k is out of bounds

      throw new IndexOutOfBoundsException();
      }

  if (k == 0){                                // this handles k = 0 condition
      head = head.next;
  }

  else

  for (int i = 0; i < k-1; i++){              // otherwise, if K != 0,
      current = current.next;                 // move pointer to k position

  }

  if (current != null) {
        current.next = current.next.next;
  }

  N--;  

  }

这给了我希望的输出。