我一直在练习破解编码面试的问题,我想出了一个问题,要求删除链表中的中间节点。
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
?
答案 0 :(得分:1)
回答你的问题,因为它是死代码的一个例子。它是一个局部变量,因为任何代码都不会读取它的最终写入,它对程序没有任何影响。
那是:
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
删除node2
,应该转到:
node1 -> node3 -> node4
| | |
data1 data3 data4
但是你移动数据就好像在数组中一起移动项目一样。这导致它:
node1 -> node2 -> node3
| | |
data1 data3 data4
永远不需要为任何链表操作重新分配 current.data
。
答案 1 :(得分:1)
你的名单是否有双重联系?在这种情况下,你可以做到
if (mid != null) {
mid.prev.next = mid.next
mid.next.prev = mid.prev
}
让垃圾收集变得神奇。
在任何情况下,要回答您的问题,请认识到Java中对象(例如Node
)的变量始终是引用(指针)。
在您的函数中,current
是一个指向Node对象的变量。如果将其设置为null
,则不会指向任何位置。但这不会改变列表的结构。
答案 2 :(得分:1)
如果它是双链表,我们需要将mid.pre链接到mid.next,如果它是单链接列表,我们需要从头到尾遍历(我们需要先前的节点Prv.next = mid
)并且只需替换{{ 1}}。
问题:在您的两个解决方案中,我们如何在移除中间节点之后从头部进行遍历?
答案 3 :(得分:0)
我不明白为什么它首先没有给出以下代码的编译错误:
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;
}