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