>我有一个C程序,它拆分了一个链表。逻辑是这样的 - 如果链表有偶数个节点,则将其分成相等的两半。否则将其与父链表比子链表多一个节点的父链表拆分。当我运行下面的代码时,主循环中的display_LL函数会正确打印"p"链表。它的分裂正确。但是display_LL函数打印的"r"链表为空。
而当我从"frontbacksplit_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.
}
问题是你传递指针p
并按值q
。因此,当您在函数内部更改它们时frontbacksplit_LL
这些更改在函数外部不可见。您应该通过指针而不是值传递指针,例如
frontbacksplit_LL(struct node **a,struct node **b,int node_count)
当然,您必须将函数代码中的所有a
和b
替换为 *a
和 *b
.
这是因为指针变量p
和r
是按值传递给函数frontbacksplit_LL
的。因此,在函数frontbacksplit_LL
内部所做的任何更改都是函数的本地更改(当您更改副本时(。
由于您希望对函数中变量a
和b
所做的更改frontbacksplit_LL
反映在变量p
和main
中的q
中,因此您需要按地址传递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));
问题就在这里:
struct node *p,*q,*r;
frontbacksplit_LL(p, r, count(p));
为了正确执行此操作,您需要将r
声明为指向后半部分的指针。在您的代码中,r
是按值传递的,因此结果存储在 frontbacksplit_LL
的局部变量b
中。如果您传递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
访问列表。
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;
}
顺便说一句:main(( 应该返回 int。