圆形链接列表在尝试打印时崩溃

时间:2016-03-21 21:44:35

标签: c loops pointers linked-list

所以我正在研究一个程序,它最终会模拟一只跛鸭版鸭鸭(实际上被教授称为鸭鸭靴)。当我读到问题时,循环链表是向我突然出现的。虽然我一般都很擅长使用链表。

程序似乎正在创建和分配节点,但是当我尝试打印时,我崩溃了。

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

typedef struct {
    char name[20];
    struct jimmysFriend *next;
} jimmysFriend;

jimmysFriend *createNode();
void populateList(jimmysFriend *bestFriend, int numberOfFriends);
//void duckDuckBoot();
void printList(jimmysFriend *bestFriend);

int main(void) {
    int i;
    int cases;
    int numberOfFriends;
    scanf("%d", &cases);
    for (i = 0; i < cases; i++) {
        scanf("%d", &numberOfFriends);
        jimmysFriend *bestFriend; //head
        bestFriend = NULL;
        populateList(bestFriend, numberOfFriends);
        printList(bestFriend);
    }
    return 0;
}

void populateList(jimmysFriend *bestFriend, int numberOfFriends) {
    int i; //Where I actually create the circular list.
    jimmysFriend *aFriend;
    for (i = 0; i < numberOfFriends; i++) {
        aFriend = createNode();
        if (bestFriend == NULL) {
            bestFriend = aFriend;
            aFriend->next = aFriend;
        } else
        if (bestFriend != NULL) {
            jimmysFriend *temptr;
            aFriend->next = bestFriend;
            temptr = bestFriend;
            while (temptr->next != bestFriend) {
                temptr = temptr->next;
            }
            temptr->next = aFriend;
        }
    }
}

jimmysFriend *createNode() { //Creates a node
    jimmysFriend *aFriend;
    aFriend = malloc(sizeof(jimmysFriend));
    if (aFriend != NULL) {
        scanf("%s", aFriend->name);
    }
    return aFriend;
}

void printList(jimmysFriend *bestFriend) { //Problem area?
    jimmysFriend *temptr;
    temptr = bestFriend;
    while (temptr->next != bestFriend) {
        printf("%s\n", temptr->name);
        temptr = temptr->next;
    }
}

2 个答案:

答案 0 :(得分:2)

有两个问题。

首先,您未按地址将bestFriend传递给populateList(),因此不会更改。 populateList()应如下所示:

void populateList(jimmysFriend **bestFriend, int numberOfFriends){
    int i; //Where I actually create the circular list.
    jimmysFriend* aFriend;
    for(i = 0; i < numberOfFriends; i++){
        aFriend = createNode();
        if(*bestFriend == NULL){
            *bestFriend = aFriend;
            aFriend->next = aFriend;
        }
        else if(*bestFriend != NULL){
            jimmysFriend* temptr;
            aFriend->next = *bestFriend;
            temptr = *bestFriend;
            while(temptr->next != *bestFriend){
                temptr = temptr-> next;
            }
            temptr->next = aFriend;
        }
    }
}

然后你这样称呼它:

populateList(&bestFriend, numberOfFriends);

第二个问题是你printList()循环的条件是错误的。编写它的方法不止一种,但这个do循环有效:

void printList(jimmysFriend* bestFriend){ //Problem area?
    if (bestFriend != NULL) {
        jimmysFriend* temptr = bestFriend;
        do {
            printf("%s\n", temptr->name);
            temptr = temptr->next;
        } while (temptr != bestFriend);
    }
}

参考:Circular Linked List

答案 1 :(得分:1)

在populateList()中,当你完成这个功能时,吉米最好的朋友并没有真正指向列表的头部。您在populateList()中进行的赋值将丢失。

将jimmy的最好朋友作为指向该函数的指针的地址。所以populateList()将接受jimmysFriend ** bestFriend。然后,当您尝试将头部存储在那里时,您将为想要成为* bestFriend的头部分配节点。

您可以随时通过在调用printList()之前检查Jimmy的最好朋友是否为NULL来验证。

populateList ( &bestFriend, numberOfFriends);