Data structures 当只给出指向某个节点的指针时,从单个链接列表中删除该节点
这是在一次采访中向我提出的一个问题 内存中有一个单一的链表。您必须删除一个节点。您需要编写一个函数来删除该节点,该函数只将要删除的节点的地址作为输入,不接受任何其他内容(包括头) 我给出的答案与下面帖子中的答案类似——将下一个节点的内容复制到要删除的节点中,然后删除下一个节点 但是面试官又问我,如果我传递最后一个节点的地址会怎么样。我告诉他,因为下一个将是NULL,所以将该NULL与下一个节点的地址(也是NULL)一起复制到数据字段中。然后他告诉我会有悬空指针的问题。。。我一点也不明白。有人能解释一下这个问题吗?有没有通用的解决方案 更新(两天后):增加一点。考虑到列表末尾没有特殊节点。最后一个节点指向NULL,如果该节点作为输入给定,那么如何使前一个节点指向NULL。还是不可能Data structures 当只给出指向某个节点的指针时,从单个链接列表中删除该节点,data-structures,linked-list,Data Structures,Linked List,这是在一次采访中向我提出的一个问题 内存中有一个单一的链表。您必须删除一个节点。您需要编写一个函数来删除该节点,该函数只将要删除的节点的地址作为输入,不接受任何其他内容(包括头) 我给出的答案与下面帖子中的答案类似——将下一个节点的内容复制到要删除的节点中,然后删除下一个节点 但是面试官又问我,如果我传递最后一个节点的地址会怎么样。我告诉他,因为下一个将是NULL,所以将该NULL与下一个节点的地址(也是NULL)一起复制到数据字段中。然后他告诉我会有悬空指针的问题。。。我一点也不明白。有人能
简单地说:如果一个节点作为一个函数的输入,如何使引用它的指针指向NULL如果有其他元素指向下一个节点,这些元素将被复制到当前节点,然后被删除,那么这个操作将引入错误。因此,在您的回答中,您应该强调,您的解决方案只有在没有外部引用列表的情况下才有效 只有当数据结构使用特定的“last node”元素进行扩充时,您的解决方案才能使用最后一个节点。(如果您使用的是Smalltalk,您可以编写
self-been:nil
任何其他语言都没有类似的功能)
不,如果列表有外部引用,则没有通用解决方案。我想面试官想看看你是否真的精通这个主题,或者只是在重复一个记忆中的答案。悬空指针:
(http://en.wikipedia.org/wiki/Dangling_reference)
计算机编程中的悬空指针和野指针是
不指向适当类型的有效对象的指针。
这些是内存安全违规的特殊情况
当对象被删除或解除分配时,会出现悬空指针,
不修改指针的值,使指针仍然
指向解除分配内存的内存位置。作为系统
如果
然后原始程序取消引用(现在)悬空指针,
可能会导致不可预测的行为,因为内存现在可能包含
完全不同的数据
在您的回答中,要删除给定节点,实际上是删除下一个节点,该节点可能被指针引用。这就是悬空指针问题产生的原因
(1) 正如您在注释中所阐明的,该列表没有外部参考。
(2) 正如采访者所说,悬空指针问题可能会出现
(1)和(2)不能同时正确。这意味着某个地方有误会
关于删除最后一个节点:
但是面试官又问我,如果我把面试官的地址传过去怎么办
最后一个节点。我告诉他,既然下一个是空的,复制那个空的
与下一个节点的地址一起输入数据字段,该节点是
也为空
我认为您混淆了这两件事:(1)指向NULL的指针p,(2)数据字段中有NULL的链表节点
假设数据结构是a->b->c->d
。将NULL写入d的数据字段不会神奇地使c在其next
字段中有NULL指针
如果链表始终有一个永远不会删除的特殊最后节点,则可以删除最后一个节点。例如,a->b->c->d->LAST
其中LAST在其数据字段中有一个特殊值,表示它实际上是最后一个元素。现在要删除d,可以删除最后一个,并在d的数据字段中写入特殊值
也许这些正是你在面试中想要说的,在这种情况下,你和面试官之间一定有一些沟通错误。步骤:
void delete_node(node* node)
{
node->Data = node->Next->Data;
node* temp = node->Next->Next;
delete(node->Next);
node->Next = temp;
}
可能您的链接列表遍历可能需要假设指向
null
的任何节点都是null
节点,而不管值是多少
a->b->c->d->NULL
因此
d
是null
节点,不应将该节点视为节点。这样可以节省使用特殊值的时间,因为它们在一般意义上是不正确的。除此之外,您将没有任何其他方法使上一个节点指向null
然后应该有一个签入程序,检查给定节点是否是最后一个节点
void delete_node(node* node1)
{
node* search=head;
if(node1==head)
{
head=head->next;
search->next=NULL;
node1->next=NULL;
}
while(search->next != node1)
search=search->next;
if(node1->next==NULL)
{
search->next=NULL;
}
else
{
search->next=node1->next;
node1->next=NULL;
}
delete node1;
}
假设:deleteNode()引用了节点指针 没有while循环的简单解决方案。在deleteNode()中,if case处理头节点和中间节点的删除,而else处理最后一个节点的删除
#include <iostream>
using namespace std;
class Node{
public:
int data;
Node* next;
Node(int d): data(d){}
};
void insert(Node* &head, int data){
Node *node = new Node(data);
node->next = head;
head = node;
}
void print(Node *head){
Node *temp = head;
while(temp !=NULL){
cout << temp->data <<" ";
temp = temp->next;
}
cout << endl;
}
void deleteNode(Node *&node){
cout << "Deleting "<<node->data<<endl;
if(node->next != NULL){
Node *t = node->next;
node->data = node->next->data;
node->next = node->next->next;
delete t;
}else{
delete node;
node = NULL;
}
}
int main(int argc, char const *argv[]) {
Node *head = NULL;
insert(head, 10);
insert(head, 20);
insert(head, 30);
insert(head, 40);
insert(head, 50);
print(head);
deleteNode(head->next); //delete 40
deleteNode(head->next->next->next); //delete last node 10
print(head);
return 0;
}
#包括
使用名称空间std;
类节点{
公众:
int数据;
节点*下一步;
节点(intd):数据(d){}
};
无效插入(节点*&头部,整数数据){
节点*节点=新节点(数据);
节点->下一步=头部;
头部=节点;
}
无效打印(节点*头){
节点*温度=头部;
while(temp!=NULL){
cout data next=节点->下一步->下一步;
删除t;
}否则{
删除节点;
node=NULL;
}
}
int main(int argc,char const*argv[]{
Node*head=NULL;
插入(头,10);
插入(头,20);
插入(头,30);
插入(头,40);
插入(头,50);
打印头;
删除节点(
#include <iostream>
using namespace std;
class Node{
public:
int data;
Node* next;
Node(int d): data(d){}
};
void insert(Node* &head, int data){
Node *node = new Node(data);
node->next = head;
head = node;
}
void print(Node *head){
Node *temp = head;
while(temp !=NULL){
cout << temp->data <<" ";
temp = temp->next;
}
cout << endl;
}
void deleteNode(Node *&node){
cout << "Deleting "<<node->data<<endl;
if(node->next != NULL){
Node *t = node->next;
node->data = node->next->data;
node->next = node->next->next;
delete t;
}else{
delete node;
node = NULL;
}
}
int main(int argc, char const *argv[]) {
Node *head = NULL;
insert(head, 10);
insert(head, 20);
insert(head, 30);
insert(head, 40);
insert(head, 50);
print(head);
deleteNode(head->next); //delete 40
deleteNode(head->next->next->next); //delete last node 10
print(head);
return 0;
}