Java 是否将当前节点设置为空?

Java 是否将当前节点设置为空?,java,linked-list,nodes,Java,Linked List,Nodes,我一直在练习破解编码面试的问题,我想出了一个解决方案,解决了一个问题,要求删除链接列表中的中间节点 public void deleteMidNode(Node mid){ if(mid == head || mid.next==null){ return; } Node current = mid; while(current.next.next!=null){ current.data = current.next.data;

我一直在练习破解编码面试的问题,我想出了一个解决方案,解决了一个问题,要求删除链接列表中的中间节点

 public void deleteMidNode(Node mid){
    if(mid == head || mid.next==null){
        return;
    }
    Node current = mid;
    while(current.next.next!=null){
        current.data = current.next.data;
        current = current.next;
    }
    current.next = null;
}
现在这段代码可以工作了——我已经测试过了。然而,我很好奇为什么我可以将
current.next
设置为null,但如果我这样做,它就不起作用了:

 public void deleteMidNode(Node mid){
    if(mid == head || mid.next==null){
        return;
    }

    Node current = mid;
    while(current.next!=null){
        current.data = current.next.data;
        current = current.next;
    }
    current = null;     
}

谁能告诉我为什么不能将当前节点设置为
null

来回答您的问题,因为这是一个死代码的例子。它是一个局部变量,因此,由于对它的最终写入不会在以后被任何代码读取,因此它对程序没有任何影响

即:

    current = null;
    //there are no reads of "current" here before:
} //the end of method which is the end of scope for the local "current"
一个像样的IDE会向您暗示这段代码没有被读取,例如,灰显、下划线或以其他方式突出显示死代码

我认为不值得过于仔细地分析您的代码,尽管这恐怕是完全错误的,从链表中删除项目应该是一个O(1)恒定时间过程(至少在找到节点和上一个节点后)。您正在四处移动数据,使其成为O(n),这意味着它的效率并不比从数据数组中删除更高

鉴于此:

node1 -> node2 -> node3 -> node4
  |        |        |        |
data1    data2    data3    data4
删除节点2应转到:

node1 -> node3 -> node4
  |        |        |
data1    data3    data4
但移动数据就像在数组中移动项目一样。这导致:

node1 -> node2 -> node3
  |        |        |
data1    data3    data4

当前。任何链接列表操作都不需要重新分配数据。

您的列表是双链接的吗?在这种情况下,你可以这样做

if (mid != null) {
    mid.prev.next = mid.next
    mid.next.prev = mid.prev
}
让垃圾收集发挥它的魔力

在任何情况下,要回答您的问题,请认识到Java中对象(如
节点
)的变量始终是引用(指针)


在函数中,
current
是一个指向节点对象的变量。如果将其设置为
null
,则它不会指向任何地方。但这并不会改变列表的结构。

如果它是一个双链接列表,我们只需要将mid.pre链接到mid.next,如果它是单链接列表,我们需要从开始到中间遍历(我们需要上一个节点
Prv.next=mid
),然后替换
Prv.next=mid.next


问题:在两种解决方案中,移除中间节点后,我们如何从头部进行遍历

我不明白为什么它不首先给出以下代码的编译错误:

current = current.next;
这将导致编译错误,因为您正在将节点指针分配给节点

当我在传递指针的同时运行相同的函数时,它会工作

#include<stdio.h>
#include<malloc.h> // C library to handle malloc functions

struct node{ // struct node declaration
    int data;
    struct node* link;
};
void deleteNode(struct node*);
void printList(struct node*);
int main(){
    struct node* head;
    struct node* first;
    struct node* second;
    struct node* third;
    struct node* fourth;
    struct node* fifth;
    struct node* sixth;
    head = (struct node*)malloc(sizeof(struct node));
    first = (struct node*)malloc(sizeof(struct node));
    second = (struct node*)malloc(sizeof(struct node));
    third = (struct node*)malloc(sizeof(struct node));
    fourth = (struct node*)malloc(sizeof(struct node));
    fifth = (struct node*)malloc(sizeof(struct node));
    sixth = (struct node*)malloc(sizeof(struct node));
    head->link = first;
    first->link = second;
    second->link = third;
    third->link = fourth;
    fourth->link = fifth;
    fifth->link = sixth;
    sixth->link = NULL;
    head-> data = 1; 
    first-> data = 2;
    second-> data = 3;
    third-> data = 4;
    fourth-> data = 5;
    fifth-> data = 6;
    sixth-> data = 7;
    printList(head);
    deleteNode(second);
    printList(head);
}
void printList(struct node* head){
    struct node* node = head;
    while(node->link!= NULL){
        printf("%d\n",node->data);
        node= node->link;
    }
}
void deleteNode(struct node* kid){
    struct node* mid = kid;
    while(mid->link!= NULL){
        mid->data = mid->link->data;
        mid = mid->link;
    }
    mid = NULL;
}
#包括
#包含//C库以处理malloc函数
结构节点{//结构节点声明
int数据;
结构节点*链接;
};
void deleteNode(结构节点*);
无效打印列表(结构节点*);
int main(){
结构节点*头部;
结构节点*第一;
结构节点*second;
结构节点*3;
结构节点*4;
结构节点*5;
结构节点*sixth;
head=(结构节点*)malloc(sizeof(结构节点));
first=(结构节点*)malloc(sizeof(结构节点));
第二个=(结构节点*)malloc(sizeof(结构节点));
第三个=(结构节点*)malloc(sizeof(结构节点));
第四个=(结构节点*)malloc(sizeof(结构节点));
fifth=(结构节点*)malloc(sizeof(结构节点));
第六个=(结构节点*)malloc(sizeof(结构节点));
头->链接=第一;
第一->链接=第二;
第二->链接=第三;
第三->链接=第四;
第四->链接=第五;
第五->链接=第六;
第六->链接=空;
头部->数据=1;
第一->数据=2;
第二->数据=3;
第三->数据=4;
第四->数据=5;
第五->数据=6;
第六->数据=7;
印刷品清单(标题);
删除节点(第二);
印刷品清单(标题);
}
无效打印列表(结构节点*头){
结构节点*节点=头部;
while(节点->链接!=NULL){
printf(“%d\n”,节点->数据);
节点=节点->链接;
}
}
void deleteNode(结构节点*kid){
结构节点*mid=kid;
while(中间->链接!=NULL){
中间->数据=中间->链接->数据;
中间=中间->链接;
}
mid=NULL;
}

如果是头部还是尾部,为什么要中断?
current=null
仅重新分配此变量的值。它不会更改基础的
节点
对象。这是不正确的,从链表中删除项目应该是一个O(1)常量时间过程。您正在移动数据,使其成为O(n)结构是链表还是双链表?也就是说,您可以访问一个节点的前置节点(
node.prev
),或者只有
节点。next
?对于双链接列表,您还必须更新以下节点的prev指针:
mid.next.prev=mid.prev