Связанный список в C, список строится правильно? - PullRequest
2 голосов
/ 25 января 2012

Я пытаюсь реализовать абстракцию связанного списка, однако у меня возникают проблемы. Однажды я создаю связанный список и добавляю в него элементы. Когда я печатаю список, он печатает только первый элемент в нем в виде бесконечного цикла, что означает, что либо первый элемент связан с самим собой, либо функция печати неверна. Тем не менее, я не могу найти проблему, кто-то может помочь?

Ниже приведена абстракция списка:

typedef struct _friend {
    char *firstname;
    char *lastname;
    char birthdate[9];
} friend;


typedef struct _node {
    friend *value;
    struct _node *next;
} node;

typedef struct _linkedlist {
    node *head;
} linkedlist;

Программа должна следовать этой абстракции, поскольку она является частью чего-то большего. Ниже приведены функции, которые должны печатать список и добавлять узел в начало списка:

 /* addHead
  *
  * This function takes two parameters - a linked list and a friend.
  * This creates a node for the linked list and connects the friend to the 
  * node.  Then it adds the node to the head of the linked list.
  */

void addHead(linkedlist *llist, friend *f)
{

    // create a node and put the friend in it
    node *n = (node *)malloc(sizeof(node));
    n->value = f;
    n->next = NULL;

    // if the list is empty
    if (llist == NULL)
    {
        // this link is the entire list
        llist->head = n;
        printf("adding friend to null list\n");

    }
    // if the list is not empty
    else
    {
        // make the new link's next pointer point to
        // the first link in the list
        n->next = llist->head;
        printf("adding %s to head\n", n->value->firstname);

        //  make the head pointer point to the new link
        llist->head = n;


}

}

/*
 * printList
 *
 * This steps down through each of the nodes in a linked list and 
 * prints out the information stored in the friend to which the node points.
 * Instead of automatically printing to the screen, it prints to the 
 * file pointer passed in.  If the programmer wants to print to the screen,
 * he/she will pass in stdout.
 */

void printList(linkedlist *llist,FILE *fp)
{

    node *n;
    friend *f;
    // for each node, print out the friend attached to it

    for(n = llist->head; n != NULL ; n = llist->head->next)
    {
        // assign f to the friend of the right node
        f = n->value; 
        // print the friend out
        fprintf(fp,"%s %s: %s\n",
        f->firstname, f->lastname, f->birthdate);
    }

}

Спасибо

Ответы [ 4 ]

3 голосов
/ 25 января 2012

Цикл for в printList не совсем верен:

for(n = llist->head; n != NULL ; n = llist->head->next)

Это должно выглядеть так:

for(n = llist->head; n != NULL ; n = n->next)

В противном случае, начиная со второй итерации, nкаждый раз устанавливается на одно и то же значение.

Следующее не связано с вашей проблемой, но я все равно упомянул об этом.В следующем коде:

if (llist == NULL)
{
    // this link is the entire list
    llist->head = n;
    printf("adding friend to null list\n");

}

, если llist == NULL, то llist->head = n выйдет из-за ошибки.

С текущей подписью addHead() мало что можно сделать, если llist - это NULL (кроме печати сообщения об ошибке и аварийного отключения).

Если вместо этого вы хотели проверить, является ли llist->head НЕДЕЙСТВИТЕЛЬНЫМ, вам не нужно это делать, поскольку elseБлок уже обрабатывает это правильно.

0 голосов
/ 26 января 2012

Я сделал следующее для вашей программы:

  • слегка изменил структуру friend.Для удобства объявлены имя и фамилия как массивы.
  • Написал main(), который вызывает другие функции
  • Проверка ошибок в addHead()
  • Добавлена ​​create_friend() функция, которая создает friend struct
  • добавлено freeList() для освобождения памяти, которая была malloc() 'ed
  • исправлена ​​ошибка зацикливания в вашей функции печати

Итак, все идет ..

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct _friend {
    char firstname[10];
    char lastname[10];
    char birthdate[9];
} friend;


typedef struct _node {
    friend *value;
    struct _node *next;
} node;

typedef struct _linkedlist {
    node *head;
} linkedlist;


void addHead(linkedlist *llist, friend *f)
{
    node *n = NULL;

    if (( n = (node *)malloc(sizeof(node))) == NULL) {
        printf("unable to allocate memory \n");
        exit(1);
    }

    n->value = f;
    n->next = NULL;

    if (llist == NULL) {
        llist->head = n;
        printf("adding friend to null list\n");
    } else {
        n->next = llist->head;
        printf("adding %s to head\n", n->value->firstname);
        llist->head = n;
    }

    return;
}

void printList(linkedlist *llist)
{
    node *n;
    friend *f;

    if (llist->head == NULL) {
        printf("Empty list \n");
        return;
    }

    for(n = llist->head; n != NULL ; n = n->next) {
        f = n->value; 
        printf("%s %s %d \n", f->firstname, f->lastname, f->birthdate);
    }

    return;
}

friend * create_friend(char *fn, char *ln, char *dob)
{
    friend *fp = NULL;

    if ((fp = malloc(sizeof(friend))) == NULL) {
        printf("unable to allocate memory \n");
        exit(1);
    }

    strcpy(fp->firstname, fn);
    strcpy(fp->lastname, ln);
    strcpy(fp->birthdate, dob);

    return fp;
}

void freeList(linkedlist *llist)
{
    node *cur = llist->head;
    node *prev = cur; 
    friend *f;

    while (cur != NULL) {
        prev = cur; 
        cur = cur->next;
        f = prev->value;
        printf("freeing .. %s %s %d \n", f->firstname, f->lastname, f->birthdate);
        free(prev->value);
        free(prev);
    }    

    return;
}

int main(void)
{
    linkedlist ll;
    friend *f;

    ll.head = NULL;

    f = create_friend("firstname1", "lastname1", "12345678");
    addHead(&ll, f);

    f = create_friend("firstname2", "lastname2", "12345678");
    addHead(&ll, f);

    f = create_friend("firstname3", "lastname3", "12345678");
    addHead(&ll, f);

    printList(&ll);

    freeList(&ll);
    ll.head = NULL;

    printList(&ll);

    return 0;
}

Надеюсь, это поможет!

0 голосов
/ 25 января 2012

Должно быть n = n -> next, иначе вы просто получаете следующую голову каждый раз.

0 голосов
/ 25 января 2012

Попробуйте:

void printList(linkedlist *llist,FILE *fp)
{

    node *n;
    friend *f;
    // for each node, print out the friend attached to it

    for(n = llist->head; n != NULL ; n = n->next)
    {
        // assign f to the friend of the right node
        f = n->value; 
        // print the friend out
        fprintf(fp,"%s %s: %s\n",
        f->firstname, f->lastname, f->birthdate);
    }

}
...