简体   繁体   English

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

[英]How to delete the first element in a linked list?

I am trying to write a function delete() that takes a linked list and deletes the Kth element from the list. 我正在尝试编写一个函数delete(),该函数接受一个链接列表并从列表中删除第K个元素。 My code is below. 我的代码如下。

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;
  }
}

} }

So far my code works as expected when I run a command such as lst1.delete(1) or lst1.delete(2) in main. 到目前为止,当我在main中运行lst1.delete(1)lst1.delete(2)类的命令时,我的代码可以按预期工作。 However, when I run lst1.delete(0) , it deletes the entire linked list. 但是,当我运行lst1.delete(0) ,它将删除整个链表。 I cannot figure out why lst1.delete(0) is deleting the entire linked list, but I think is has something to do with the for-loop. 我不知道为什么lst1.delete(0)删除整个链表,但是我认为这与for循环有关。 The for-loop is loops up until one less than k. for循环一直循环直到小于k。 If I pass in 0, then perhaps it is deleting the head entry point, which is deleting the entire list? 如果我输入0,则可能是删除头入口点,即删除整个列表?

My question is, can anybody please tell me how I can change my code so that when I run lst1.delete(0) , it just deletes the first element in the linked list, and not the entire linked list? 我的问题是,有人可以告诉我如何更改代码,以便当我运行lst1.delete(0) ,它只是删除链表中的第一个元素,而不是整个链表吗?

This should fix your issue. 这应该可以解决您的问题。 You are setting 您正在设定

head = null; 

if the item to remove is the head, but what you should do is, 如果要移除的物品是头部,但是您应该做的是,

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

    head = null;
}

This will point the head to head + 1 item, unless head is the only item in the list. 除非head是列表中的唯一项,否则这将使head朝向head + 1项。 in that case we should set head to null. 在这种情况下,我们应该将head设置为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;
            }
        }
    }
}

You problem is here 你的问题在这里

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

if you use lst1.delete(0) then head.item.equals(e) become true as you pass head to remove() . 如果你使用lst1.delete(0)然后head.item.equals(e)为您传递成为真正的head ,以remove() Then your entire linked removed. 然后将整个链接删除。

One fix would be 一种解决方法是

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

Here extra check head.next==null ensure that there have only one element in the linked list. 在这里,额外检查head.next==null确保链表中只有一个元素。

1) delete(0). 1)删除(0)。 delete never enters loop because i less than k is true straight away. delete永远不会进入循环,因为我小于k立刻就成为真。 So you remove head.item. 因此,您删除head.item。 2) Then remove special case 2 sets head = null. 2)然后删除特殊情况2 set head = null。

That's 2 mistakes. 那是两个错误。 No offence but your code is a mess. 没有冒犯,但您的代码是一团糟。 Sit down with diagrams and try puzzling it from scratch again. 坐在图表上,尝试再次从头开始困惑。 Someone else doing it for you will teach you nothing except how to give up on a programming problem early. 别人为您做的事情,除了如何尽早放弃编程问题之外,什么都不会告诉您。

This reason is because when k = 0, the loop is never entered. 这是因为,当k = 0时,永远不会进入循环。 As a result, current is not updated to point to the right one. 结果, current不会更新为指向正确的current

I figured out another method that does not even call the remove method. 我想出了另一种甚至不调用remove方法的方法。 Since I was not the one who originally wrote the remove method, I prefer the code below over the others only because it stays within its self as far as method calling goes. 因为我不是最初编写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--;  

  }

This gave me the output I was hoping for. 这给了我希望的输出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM