[英]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.