删除链表的最后一个节点,并将其添加到另一个链表
Remove last node of a linked list, and add this to another linked list
我正在尝试弄清楚如何操作链表。我想删除给定链表的结束节点并将其添加到另一个给定链表的末尾。
出于某种原因,我无法得到正确的指示,好吧 - 至少那是我认为的问题所在。
(此方法位于一个 while 循环中,因此一个列表不断变小,而另一个列表不断增长。)
void movenode(struct Node **cards,struct Node **column)
{
struct Node *head = NULL;
struct Node *tmp,*head1 = *cards;
struct Node *tmp2,*head2 = *column;
if (*cards == NULL || (*cards)->next == NULL){
return;
}
while (tmp->next != NULL) {
head->next = tmp;
tmp = tmp->next;
}
while (tmp2->next != NULL) {
tmp2 = tmp2->next;
}
head->next = NULL;
tmp2->data = tmp;
tmp2->next = NULL;
*cards = head1;
*column = head2;
}
希望有人能帮助我更好地理解这一点。
我不完全确定你的解决方案的机制,所以我将提供一个单独的实现和解决方案。
typedef struct Node {
void *data;
struct Node *next;
}
void poppush(Node *popHead, Node *pushHead) {
Node *pushLastNode = pushHead;
while (pushLastNode->next != NULL) {
pushLastNode = pushLastNode->next;
}
Node *popLastNode = popHead;
while (popLastNode->next != NULL) {
popLastNode = popLastNode->next;
}
Node *popSecondLastNode = popHead;
while (popSecondLastNode->next != popLastNode) {
popSecondLastNode = popSecondLastNode->next;
}
popSecondLastNode->next = NULL;
pushLastNode->next = popLastNode;
}
但是,对于此类操作,我建议使用 doubly-linked 列表 and/or 创建一些专用于管理列表的函数。
For some reason I can not get my pointers right, well.. atleast that is where I think the problem lays.
你说得对,但还不止于此。例如,在 struct Node *head = NULL;
之后,没有任何内容会修改 head
中的值,因此每次您执行 head->next
时,您都在访问“NULL + 一个小偏移量”的内存(并且可能会崩溃)。
要从单链表中删除最后一个条目,您必须找到最后一个条目之前的条目(以便您可以修改其next
);并且要将条目添加到链接列表中,您必须找到最后一个条目(以便您可以修改其 next
)。考虑到这一点,我们可以将其分为 5 个部分:
进行完整性检查
查找 *cards
列表中最后一个条目之前的条目
删除 *cards
列表中的最后一个条目
找到 *column
列表中的最后一个条目
将(删除的)条目添加到 *columns
列表的末尾
您可以一次实现这 5 个部分中的每一个(并测试它们)。这是编程的重要组成部分 - 将更复杂的东西分解成更简单的东西。
生成的代码可能类似于(未经测试):
void movenode(struct Node **cards,struct Node **column) {
struct Node *temp = *cards;
struct Node *removed;
// Do sanity checks
if (temp == NULL) {
return;
}
// Find the entry before the last entry in the `*cards` list
if(temp->next != NULL) {
while(temp->next->next != NULL) {
temp = temp->next;
}
}
// Remove the last entry in the `*cards` list
if(temp == NULL) {
// The last entry was the first entry
removed = temp;
*cards = NULL;
} else {
removed = temp->next;
temp->next = NULL;
}
// Find the last entry in the `*column` list
temp = *column;
if(temp != NULL) {
while(temp->next != NULL) {
temp = temp->next;
}
}
// Add the (removed) entry to the end of the `*columns` list
if(temp == NULL) {
// There was no last entry (list was empty)
*column = removed;
} else {
temp->next = removed;
}
}
我正在尝试弄清楚如何操作链表。我想删除给定链表的结束节点并将其添加到另一个给定链表的末尾。
出于某种原因,我无法得到正确的指示,好吧 - 至少那是我认为的问题所在。
(此方法位于一个 while 循环中,因此一个列表不断变小,而另一个列表不断增长。)
void movenode(struct Node **cards,struct Node **column)
{
struct Node *head = NULL;
struct Node *tmp,*head1 = *cards;
struct Node *tmp2,*head2 = *column;
if (*cards == NULL || (*cards)->next == NULL){
return;
}
while (tmp->next != NULL) {
head->next = tmp;
tmp = tmp->next;
}
while (tmp2->next != NULL) {
tmp2 = tmp2->next;
}
head->next = NULL;
tmp2->data = tmp;
tmp2->next = NULL;
*cards = head1;
*column = head2;
}
希望有人能帮助我更好地理解这一点。
我不完全确定你的解决方案的机制,所以我将提供一个单独的实现和解决方案。
typedef struct Node {
void *data;
struct Node *next;
}
void poppush(Node *popHead, Node *pushHead) {
Node *pushLastNode = pushHead;
while (pushLastNode->next != NULL) {
pushLastNode = pushLastNode->next;
}
Node *popLastNode = popHead;
while (popLastNode->next != NULL) {
popLastNode = popLastNode->next;
}
Node *popSecondLastNode = popHead;
while (popSecondLastNode->next != popLastNode) {
popSecondLastNode = popSecondLastNode->next;
}
popSecondLastNode->next = NULL;
pushLastNode->next = popLastNode;
}
但是,对于此类操作,我建议使用 doubly-linked 列表 and/or 创建一些专用于管理列表的函数。
For some reason I can not get my pointers right, well.. atleast that is where I think the problem lays.
你说得对,但还不止于此。例如,在 struct Node *head = NULL;
之后,没有任何内容会修改 head
中的值,因此每次您执行 head->next
时,您都在访问“NULL + 一个小偏移量”的内存(并且可能会崩溃)。
要从单链表中删除最后一个条目,您必须找到最后一个条目之前的条目(以便您可以修改其next
);并且要将条目添加到链接列表中,您必须找到最后一个条目(以便您可以修改其 next
)。考虑到这一点,我们可以将其分为 5 个部分:
进行完整性检查
查找
*cards
列表中最后一个条目之前的条目删除
*cards
列表中的最后一个条目找到
*column
列表中的最后一个条目将(删除的)条目添加到
*columns
列表的末尾
您可以一次实现这 5 个部分中的每一个(并测试它们)。这是编程的重要组成部分 - 将更复杂的东西分解成更简单的东西。
生成的代码可能类似于(未经测试):
void movenode(struct Node **cards,struct Node **column) {
struct Node *temp = *cards;
struct Node *removed;
// Do sanity checks
if (temp == NULL) {
return;
}
// Find the entry before the last entry in the `*cards` list
if(temp->next != NULL) {
while(temp->next->next != NULL) {
temp = temp->next;
}
}
// Remove the last entry in the `*cards` list
if(temp == NULL) {
// The last entry was the first entry
removed = temp;
*cards = NULL;
} else {
removed = temp->next;
temp->next = NULL;
}
// Find the last entry in the `*column` list
temp = *column;
if(temp != NULL) {
while(temp->next != NULL) {
temp = temp->next;
}
}
// Add the (removed) entry to the end of the `*columns` list
if(temp == NULL) {
// There was no last entry (list was empty)
*column = removed;
} else {
temp->next = removed;
}
}