Разделить связанный список показывает пустой за пределами области действия функции - PullRequest
2 голосов
/ 08 февраля 2012

У меня есть программа на C, которая разбивает связанный список.Логика такова: если связанный список имеет четное количество узлов, разбейте его на равные половины.Еще разделить его с родительским связанным списком, имеющим на один узел больше, чем дочерний связанный список.Когда я запускаю приведенный ниже код, функция display_LL в главном цикле правильно печатает связанный список 'p'.Но функция display_LL печатает связанный список 'r' NULL.

В то время как при печати связанных списков из функции 'frontbacksplit_LL' связанные списки 'p' и 'r' отображаются правильно.

Почему это другое поведение, я не могу понять.

Это проблема с областями видимости?Если да, какие изменения мне нужно внести в код?

Pls предполагает, что связанный список '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 ]

1 голос
/ 08 февраля 2012
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.

1 голос
/ 08 февраля 2012

Ваша проблема в том, что вы передаете указатели p и q по значению. Поэтому, когда вы изменяете их внутри frontbacksplit_LL, эти изменения не видны вне функции. Вы должны передавать указатели по указателям, а не по значению, например

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

Конечно, вы должны заменить все a и b в коде функции на *a и *b.

1 голос
/ 08 февраля 2012

Проблема здесь:

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 s иb s следует заменить на *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.

1 голос
/ 08 февраля 2012

Это потому, что переменные-указатели 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)); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...