到目前为止我还没有多少,但我正试图使用链接列表。
STRUCT:
struct Node
{
int value;
Node *next;
};
如何将节点添加到列表末尾?我只是试图接受一个列表头部的指针和一个作为新节点添加的int值。当我尝试运行我目前所拥有的时,我得到一个例外。
void addNode(Node* head, int x)
{
Node* temp = new Node;
temp->data = x;
temp->next = NULL;
if(!head)
{
head = temp;
return;
}
else
{
Node* last = head;
while(last->next)
last=last->next;
last->next = temp;
}
}
我还没有真正开始合并两个列表。我只知道我需要接收2个链接列表(或指向2个链表的头部?)然后遍历所有节点的列表。
E.G:链表1有3个节点:4,10,20。 链表2有4个节点:2,5,15,60。
合并列表函数将生成一个新的链表,其中包含2,4,5,10,15,20,60作为节点。
编辑:在我的主要部分,我正在调用addNode函数:
Node *head = new Node;
insertAtEnd(head,20);
这是正确的还是可能是异常的原因?
答案 0 :(得分:1)
按以下方式声明函数
void addNode( Node* &head, int x) ;
而不是此代码段
Node *head = new Node;
insertAtEnd(head,20);
你必须第一次以下列方式调用该函数
Node *head = nullptr; // or NULL
addNode(head,20);
请注意,帖子中没有名称为insertAtEnd
的函数。有函数addNode
。:)
如果您需要合并两个列表,那么您可以使用此演示程序作为示例。当然,您需要添加一些其他功能,例如删除列表以获得完整的项目。
#include <iostream>
struct Node
{
int value;
Node *next;
};
Node * insert( Node *current, int value )
{
Node *tmp;
if ( current == nullptr )
{
tmp = new Node { value, nullptr };
}
else
{
tmp = new Node { value, current->next };
current->next = tmp;
}
return tmp;
}
std::ostream & display( Node *head,
std::ostream &os = std::cout,
const char *delimiter = " " )
{
for ( ; head; head = head->next ) os << head->value << delimiter;
return os;
}
Node * merge( Node * &head1, Node * &head2 )
{
Node *new_head = nullptr;
Node *current = nullptr;
while ( head1 != nullptr && head2 != nullptr )
{
Node *tmp;
if ( head2->value < head1->value )
{
tmp = head2;
head2 = head2->next;
}
else
{
tmp = head1;
head1 = head1->next;
}
tmp->next = nullptr;
if ( new_head == nullptr )
{
new_head = tmp;
current = new_head;
}
else
{
current->next = tmp;
current = current->next;
}
}
if ( head1 != nullptr ) new_head == nullptr ? new_head : current->next = head1;
if ( head2 != nullptr ) new_head == nullptr ? new_head : current->next = head2;
head2 = nullptr;
head1 = new_head;
return new_head;
}
int main()
{
Node *list1 = nullptr;
Node *list2 = nullptr;
list1 = insert( list1, 4 );
insert( insert( list1, 10 ), 20 );
display( list1, std::cout << "List1: " ) << std::endl;
list2 = insert( list2, 2 );
insert( insert( insert( list2, 5 ), 15 ), 60 );
display( list2, std::cout << "List2: " ) << std::endl;
std::cout << std::endl;
merge( list1, list2 );
display( list1, std::cout << "List1: " ) << std::endl;
display( list2, std::cout << "List2: " ) << std::endl;
return 0;
}
程序输出
List1: 4 10 20
List2: 2 5 15 60
List1: 2 4 5 10 15 20 60
List2:
答案 1 :(得分:1)
通过这样做:
void addNode(Node* head, int x)
// here ---------^
然后是这个:
head = temp; // here
你只是修改本地head
指针,它接受从调用者传递的地址值。由于head
不是对指针的实际引用(它只是一个指针),因此结果是调用者的指针在head
保持不变时传递。你永远不会将你分配的节点附加到列表中,泄漏内存,这将成为一个悲伤的日子......
通过引用传递指针。解决这个问题,然后修复无效的data
成员(实际上应该是value
和指针指针,用于遍历列表以查找结尾),结果可能如下所示:
#include <iostream>
struct Node
{
int value;
Node *next;
};
void addNode(Node*& head, int x)
{
Node **pp = &head;
while (*pp)
pp = &(*pp)->next;
*pp = new Node;
(*pp)->value = x;
(*pp)->next = nullptr;
}
void printList(const Node *head)
{
for (; head; head = head->next)
std::cout << head->value << ' ';
std::cout << '\n';
}
void freeList(Node *&head)
{
while (head)
{
Node *p = head;
head = p->next;
delete p;
}
}
int main()
{
Node *head = nullptr;
for (int i=1; i<=5; ++i)
addNode(head, i);
printList(head);
freeList(head);
}
<强>输出强>
1 2 3 4 5
我将实现合并的任务留给您,但这足以让您获得可管理的列表并运行。
更新:来自OP的编辑问题:
Node *head = new Node;
insertAtEnd(head,20);
除了现在是一个完全不同的命名函数之外,您的节点是默认初始化的。在您的情况下,这意味着来自Node
的结果new Node;
value
和next
的 值 然后你将它传递给你的函数,它假设一个确定的值(null)来终止你的循环。
这可以通过多种方式修复;上面代码的机制就是这样一种方式。如果列表管理代码理解NULL表示无列表,则不需要首先预先分配头节点。你的addNode
原始帖子似乎至少试图遵循这个口头禅。
答案 2 :(得分:0)
这可能是例外原因:
struct Node
{
int value; <----- Node structure has value property
Node *next;
};
Node* temp = new Node;
temp->data = x; <------ Assigning to data property of Node which does not exists
temp->next = NULL;
要添加列表,您可以使用相同的方法
void addNode(Node* head, Node* head2)
{
Node* last = head;
while(last->next) last=last->next;
last->next = head2;
}
答案 3 :(得分:0)
编辑:在我的主要部分,我正在调用addNode函数:
Node *head = new Node;
insertAtEnd(head,20);
这是错误的。您没有初始化head->next
,因此在insertAtEnd
中,代码while(last->next) last=last->next;
将尝试比较未初始化的指针,如果它不为null,则会取消引用它。这可能会导致您的程序崩溃而不是抛出异常。然后,它是未定义的行为,所以任何事情都可能发生。
由于你的插入函数已经涵盖了插入空列表的情况,我只需要调用
head = nullptr;
insertAtEnd(head,20)`;
除此之外,还有一个永远不会更新函数外head
指针的错误,这已经在其他答案中得到了解释。