所以下面的代码:
/*
* For your reference:
*
* SinglyLinkedListNode {
* int data;
* SinglyLinkedListNode* next;
* };
*
*/
SinglyLinkedListNode* insertNodeAtTail(SinglyLinkedListNode* head, int data) {
SinglyLinkedListNode* temp = head;
while (temp != NULL) {
temp = temp->next;
}
SinglyLinkedListNode* temp1;
temp1->data = data;
temp1->next = NULL;
temp->next = temp1;
return temp;
}
所以,基本上我想在链接列表"head"的末尾添加"data",并返回更新后的列表。那么问题出在哪里呢?
编辑:好吧,我犯了第一个错误。但即使我换了临时工=NULL,temp->next=循环中的NULL条件仍然存在此错误
您必须为节点分配内存。记得清理分配的内存。对于每次呼叫new
,您都需要一个呼叫delete
。因此,我更喜欢智能指针。
在循环之后,temp
包含NULL
。不能取消引用空指针。
SinglyLinkedListNode* insertNodeAtTail(SinglyLinkedListNode* head, int data) {
SinglyLinkedListNode* temp1 = new SinglyLinkedListNode;
temp1->data = data;
temp1->next = nullptr;
if (!head) {
head = temp1;
return head;
}
SinglyLinkedListNode* temp = head;
while(temp->next){
temp = temp->next;
}
temp->next = temp1;
return temp;
}
此函数
SinglyLinkedListNode* insertNodeAtTail(SinglyLinkedListNode* head, int data) {
SinglyLinkedListNode* temp=head;
while(temp!=NULL){
temp=temp->next;
}
SinglyLinkedListNode* temp1;
temp1->data=data;
temp1->next=NULL;
temp->next=temp1;
return temp;
}
没有道理。在这个循环之后
while(temp!=NULL){
temp=temp->next;
}
指针CCD_ 5等于NULL。所以这个声明
temp->next=temp1;
调用未定义的行为。
指针temp1
未初始化。所以再次这些陈述
temp1->data=data;
temp1->next=NULL;
调用未定义的行为。
函数的用户不知道返回的指针是列表的头指针还是最后一个指针。因此,不清楚是将返回的指针分配给头指针,还是忽略返回的值。
该函数的外观如下。
void insertNodeAtTail( SinglyLinkedListNode * &head, int data )
{
SinglyLinkedListNode **current = &head;
while ( *current != nullptr ) current = &( *current )->next;
*current = new SinglyLinkedListNode { data, nullptr };
}
如果你主要定义了指向头节点的指针,比如
SinglyLinkedListNode *head = nullptr;
那么函数调用将看起来像
insertNodeAtTail( head, some_data );
该函数的另一个定义可以如下
SinglyLinkedListNode* insertNodeAtTail( SinglyLinkedListNode *head, int data )
{
SinglyLinkedListNode *new_node = new SinglyLinkedListNode { data, nullptr };
if ( head == nullptr )
{
head = new_node;
}
else
{
SinglyLinkedListNode *current = head;
while ( current->next != nullptr ) current = current->next;
current->next = new_node;
}
return head;
}
在这种情况下,如果你主要定义了指向头节点的指针,比如
SinglyLinkedListNode *head = nullptr;
那么函数调用将看起来像
head = insertNodeAtTail( head, some_data );
在这两个函数定义之间,第一个函数定义是优选的,因为不需要记住将返回的指针分配给头节点。
请记住,如果您有一个单链列表,并且希望将新节点附加到列表的尾部,那么最好定义双侧单链列表。在这种情况下,列表定义可能看起来像
class SinglyLinkedList
{
private:
struct Node
{
int data,
Node *next;
} *head = nullptr, *tail = nullptr;
public:
SinglyLinkedList() = default;
void insertNodeAtHead( int data );
void insertNodeAtTail( int data );
// other member functions;
};
它也在这里崩溃:
SinglyLinkedListNode* temp1;
temp1->data=data;
当到达循环while(temp!=NULL){
的末尾时,这里的temp
就是NULL
。下面您使用的语句类似于temp->next=temp1;
,这会导致崩溃