void AlternatingSplit(struct Node* source, struct Node** aRef,
struct Node** bRef)
{
/* split the nodes of source to these 'a' and 'b' lists */
struct Node* a ;
struct Node* b;
struct Node* current = source;
if(current){
a=current;
b=current->next;
current=b->next;
a->next=NULL;
b->next=NULL;
}
while(current) {
a->next=current;
b->next=current->next;
if(b)
current=b->next;
b=b->next;
a=a->next;
}
*aRef = a;
*bRef = b;
}
我在这里遇到了细分错误,我不知道为什么请帮助。
这个问题是交替分割链表节点。我使用两个指针a和b并交替添加它,但是给出了错误。请帮助我
答案 0 :(得分:2)
像大多数链表重排练习一样,指向指针的指针使工作变得非常简单。本练习的目的在于,您可以灵活地更改next
指针,而无需更改相同的数据值。指向指针的指针是用C语言做到这一点的绝佳方法。
这特别琐碎,因为已经为您提供了目标指针到指针参数,我们可以重复使用它们来构建每个列表。通过演示一种使用单个头部指针和指向指针p
的指针来构建前向链表的技术,可以最好地理解其工作原理:
struct Node *head, **pp = &head;
for (int i = 1; i <= 20; ++i)
{
*pp = malloc(sizeof **pp);
(*pp)->data = i;
pp = &(*pp)->next;
}
*pp = NULL;
是的,它需要错误检查,但是算法是这里要重点关注的。此代码仅使用pp
来构建实际列表。规则是这样的:pp
是指向Node
的指针,并且始终保留要填充的下一个指向Node
的指针的地址。那就是指针的指针所做的事情:保存指针的地址。在这种情况下,pp
最初保留头指针的地址。在添加每个新节点后,pp
会使用之前刚刚添加的节点的next
指针的地址。有道理吧?那将是我们要挂起下一个节点的下一个指针。这个过程一直持续到我们完成循环为止。指针pp
保留 last 节点的next
指针的地址,我们将其设置为NULL
以终止列表。
现在,了解了我们上面的知识后,请考虑以下问题:
void AlternatingSplit(struct Node* source, struct Node** a, struct Node** b)
{
while (source)
{
*a = source;
a = &(*a)->next;
source = source->next;
if (source)
{
*b = source;
b = &(*b)->next;
source = source->next;
}
}
*a = *b = NULL;
}
示例
下面显示了一个简短的示例,该示例同时使用了我首先显示的正向链构建算法和我之后显示的split算法。包括一些用于打印列表的实用程序功能。我将释放这些列表(现在有两个列表,请记住同时走路并释放每个节点)作为练习:
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node *next;
};
void AlternatingSplit(struct Node* source, struct Node** a, struct Node** b)
{
while (source)
{
*a = source;
a = &(*a)->next;
if ((source = source->next))
{
*b = source;
b = &(*b)->next;
source = source->next;
}
}
*a = *b = NULL;
}
void PrintList(struct Node const *p)
{
while (p)
{
printf("%d ", p->data);
p = p->next;
}
fputc('\n', stdout);
}
int main(void)
{
struct Node *head, **pp = &head;
for (int i = 1; i <= 20; ++i)
{
*pp = malloc(sizeof **pp);
(*pp)->data = i;
pp = &(*pp)->next;
}
*pp = NULL;
PrintList(head);
struct Node *a = NULL, *b = NULL;
AlternatingSplit(head, &a, &b);
PrintList(a);
PrintList(b);
return EXIT_SUCCESS;
}
输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1 3 5 7 9 11 13 15 17 19
2 4 6 8 10 12 14 16 18 20
答案 1 :(得分:1)
您的代码中几乎没有错误-
尝试解决这些问题,请参阅下面的代码以供参考。
void AlternatingSplit(struct Node* source, struct Node** aRef,
struct Node** bRef)
{
struct Node* a,b;
struct Node* current = source;
if(current){
a=current;
b=current->next;
// moving 'current' one step at a time will secure the code from crashing for corner cases
current = current->next;
if(b)
current=b->next;
a->next=NULL;
b->next=NULL;
//link aRef bRef right here
*aRef = a;
*bRef = b;
}
else {
*aRef = source; // Null
*bRef = source; // Null
return;
}
while(current)
{
a->next=current;
a=a->next;
b->next=current->next;
b=b->next;
current=current->next;
if(b){
current = b->next;
}
}
b->next = NULL;
a->next = NULL;
}
希望这会有所帮助。
继续提问,保持成长:)