拆分链表在功能范围外显示为空

时间:2012-02-08 06:24:15

标签: c pointers linked-list

我有一个分割链表的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.
}

4 个答案:

答案 0 :(得分:1)

这是因为指针变量pr通过值传递给函数frontbacksplit_LL。因此,在函数frontbacksplit_LL内进行的任何更改都是函数的本地更改(当您更改副本时)。

由于您希望对函数a中的变量bfrontbacksplit_LL所做的更改反映在p中的变量qmain中,您需要通过以下地址传递pq

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)

问题在于您按值传递指针pq。因此,当您在frontbacksplit_LL内更改它们时,这些更改在函数外部不可见。你应该通过指针而不是值来传递指针,比如

frontbacksplit_LL(struct node **a,struct node **b,int node_count)

当然,您必须使用ab替换功能代码中的所有*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)

并且所有ab应分别替换为*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。

相关问题