我有一个分割链表的C程序。逻辑是这样的 - 如果链表具有偶数个节点,则将其拆分为相等的一半。否则,将其与父链接列表分开,其中一个节点多于子链接列表。 当我运行下面的代码时,主循环中的display_LL函数会打印出' p'正确的链表.i.e。它正确分裂。但display_LL函数会打印出' r'链表NULL。
然而,当我从&frontffsp_LL'内部打印链接列表时功能,' p'和' r'链接列表显示正确。
为什么这种不同的行为,我无法理解。
这是一个范围问题吗?如果是这样,我需要在代码中做出哪些更改?
请假设链表' p'不是一个空的链表。它有节点。为清楚起见,我只是省略了代码。此外,display_LL功能代码也未显示。
struct node {
int data;
struct node *link;
};
void main()
{
struct node *p,*q,*r;
p=NULL;
q=NULL;
frontbacksplit_LL(p,r,count(p)); //Imagine p has nodes. count(p) gives number of
printf("Front_Back Splits:\n"); //nodes in the linked list.
display_LL(p); //displays split linked list correctly
display_LL(r); //Shows EMPTY linked list.
getch();
}
frontbacksplit_LL(struct node *a,struct node *b,int node_count)
{
struct node *temp;
int i,t;
temp=a;
if(node_count%2==0) //even
{
for(i=0;i<node_count/2;i++)
temp=temp->link;
b=temp->link;
temp->link=NULL;
}
else
{
for(i=0;i<(ceil(node_count/2));i++)
temp=temp->link;
b=temp->link;
temp->link=NULL;
}
display_LL(a); //Displays split linked list correctly.
display_LL(b); //Displays split linked list correctly.
}
答案 0 :(得分:1)
这是因为指针变量p
和r
通过值传递给函数frontbacksplit_LL
。因此,在函数frontbacksplit_LL
内进行的任何更改都是函数的本地更改(当您更改副本时)。
由于您希望对函数a
中的变量b
和frontbacksplit_LL
所做的更改反映在p
中的变量q
和main
中,您需要通过以下地址传递p
和q
:
frontbacksplit_LL(struct node **a, struct node **b, int node_count) {
然后通过*a
和*b
访问实际指针。在现有代码中,将a
替换为*a
,将b
替换为*b
。
并将其命名为:
frontbacksplit_LL(&p, &r, count(p));
答案 1 :(得分:1)
问题在于您按值传递指针p
和q
。因此,当您在frontbacksplit_LL
内更改它们时,这些更改在函数外部不可见。你应该通过指针而不是值来传递指针,比如
frontbacksplit_LL(struct node **a,struct node **b,int node_count)
当然,您必须使用a
和b
替换功能代码中的所有*a
和*b
。
答案 2 :(得分:1)
问题在于:
struct node *p,*q,*r;
frontbacksplit_LL(p, r, count(p));
为了正确执行,您需要将r
声明为指向后半部分的指针。在您的代码r
中按值传递,因此结果存储在b
的局部变量frontbacksplit_LL
中。如果您传递r
的地址(即&r
),则会正确完成。
函数声明应为:
frontbacksplit_LL(struct node** a, struct node** b, int node_count)
并且所有a
和b
应分别替换为*a
和*b
。然后你应该把它称为
struct node *p = NULL, *q = NULL, *r;
frontbacksplit_LL(&p, &r, count(p));
或
struct node **p = NULL, *q = NULL, **r;
frontbacksplit_LL(p, r, count(p));
在这种情况下,您需要通过*p
和*r
访问列表。
答案 3 :(得分:1)
struct llist {
struct llist *next;
char *payload;
};
struct llist *llist_split(struct llist **hnd );
struct llist *llist_split(struct llist **hnd)
{
struct llist *this, *save, **tail;
unsigned iter=0;
for (save=NULL, tail = &save; this = *hnd; ) {
if ( !this->next) break;
if ( ++iter & 1 ) { hnd = &this->next; continue; }
*tail = this;
*hnd = this->next;
tail = &(*tail)->next;
*tail = NULL;
}
return save;
}
BTW:main()应返回int。