无法反转链表 - c语言

时间:2017-06-13 08:41:49

标签: c linked-list reverse

我有一个简单的链表,每个节点都有一个字符串,int和下一个指针。

所有其他链表功能都可以工作(弹出,推送,删除节点等),但反向功能只是重复我的节点。

这是我的代码:

    personNode* reverseList(personNode* head)
    {
        personNode* curr = head;
        personNode* previous = NULL;
        personNode* next = NULL;

        while (curr != NULL)
        {
            next = curr->next;
            curr->next = previous;
            previous = curr;
            curr = next;
        }

        head = previous;
        printf("Line reversed!");

        return head;
    }

结果是:

在“倒车”之前:
before

之后:
after

(这是整个代码:)

#include <stdio.h>

#define STR_LEN 21

typedef struct personNode
{
    char name[STR_LEN];
    int age;
    char friends[3][STR_LEN];
    struct personNode* next;

}personNode;

int recursiveLength(personNode* head, int counter);
void createPerson(char name[], int age, char friends[3][STR_LEN], personNode* head);
void link(personNode* head, personNode* toLink);
char* iHaveFriends(personNode* guest, personNode* head);
int addBehindFriend(char* friendName, personNode* guest, personNode* head);
void removePersonByName(char name[], personNode* head);
void addToListTop(personNode* VIP, personNode* head);
void search(personNode* head, char name[]);
personNode* reverseList(personNode* head);
void freeList(personNode* head);

int main(void)
{
    int i = 0;
    int choice = 0;
    char name[STR_LEN] = { 0 };
    int age = 0;
    char friends[3][STR_LEN];

    personNode* head = (personNode*)malloc(sizeof(personNode));
    head->next = NULL;

    while (choice != 7)
    {
        printf("\n\nWelcome to MagshiParty Line Management Software!\nPlease enter your choice from the following options :\n1 - Print line\n2 - Add person to line\n3 - Remove person from line\n4 - VIP guest\n5 - Search in line\n6 - Reverse line\n7 - Exit\n");
        scanf("%d", &choice);

        switch (choice)
        {
            case 1:
            {
                printf("%d people in line: \n", recursiveLength(head, 0));
                recursivePrint(head);
                break;
            }

            case 2:
            {
                printf("Welcome guest!");
                printf("\nEnter name: ");
                getchar();
                scanf("%[^\t\n]s", name);
                getchar();

                printf("\nEnter age: ");
                scanf("%d", &age);

                printf("Enter names of 3 friends: ");

                for (i = 0; i < 3; i++)
                {
                    printf("\nFriend %d: ", i + 1);
                    getchar();
                    scanf("%[^\t\n]s", friends[i]);
                    getchar();
                }

                createPerson(name, age, friends, head);
                break;
            }

            case 3:
            {
                printf("Enter name to remove: ");
                getchar();
                scanf("%[^\t\n]s", name);
                getchar();

                removePersonByName(name, head);

                break;
            }

            case 4:
            {
                printf("VIP GUEST!\n");
                printf("Enter name: ");
                getchar();
                scanf("%[^\t\n]s", name);
                getchar();

                printf("Enter age: ");
                scanf("%d", &age);

                personNode* newNode = (personNode*)malloc(sizeof(personNode));

                newNode->age = age;
                strcpy(newNode->name, name);
                newNode->next = NULL;

                addToListTop(newNode, head);

                break;
            }

            case 5:
            {

                printf("Enter name to search: ");
                getchar();
                scanf("%[^t\n]s", name);
                getchar();

                search(head, name);

                break;
            }

            case 6:
            {
                head = reverseList(head);
                break;
            }

            case 7:
            {
                freeList(head);
                printf("Goodbye!");
                break;
            }

            default:
            {
                freeList(head);
                printf("Goodbye!");
                break;
            }
        }
    }

    getchar();
    getchar();
    return 0;
}

int recursiveLength(personNode* head, int counter)
{
    personNode* curr = head;
    if (head->next == NULL)
    {
        return counter;
    }
    else
    {
        if (curr->next != NULL)
        {
            counter++;
            recursiveLength(curr->next, counter);
        }
        else
        {
            return counter;
        }
    }
}

int recursivePrint(personNode* head)
{
    personNode* curr = head;
    if (head->next == NULL)
    {
        return 0;
    }
    else
    {
        if (curr->next != NULL)
        {
            printf("Name: %s, Age: %d \n", curr->name, curr->age);
            recursivePrint(curr->next);
        }
        else
        {
            return 0;
        }
    }
}

void createPerson(char name[], int age, char friends[3][STR_LEN], personNode* head)
{
    int i = 0;
    personNode* newNode = (personNode*)malloc(sizeof(personNode));

    for (i = 0; i < 3; i++)
    {
        strcpy((newNode->friends[i]), friends[i]);
        //printf("inserted = %s , bimkom - %s\n", (newNode->friends[i]), friends[i]);
    }

    newNode->age = age;
    strcpy(newNode->name, name);
    newNode->next = NULL;

    link(head, newNode);
}

void link(personNode* head, personNode* toLink)
{
    personNode* curr = head;
    int i = 0;

    if (head->next == NULL) // first node - list empty
    {
        //printf("First!");
        for (i = 0; i < 3; i++)
        {
            strcpy((head->friends[i]), (toLink->friends[i]));
            //printf("inserted = %s , bimkom - %s\n", (head->friends[i]), toLink->friends[i]);
        }
        //curr->next = malloc(sizeof(personNode));
        curr->age = toLink->age;
        strcpy(curr->name, toLink->name);
        head->next = toLink;
        //curr->next = NULL;
    }
    else
    {
        char foundFriend[STR_LEN] = { 0 };
        strcpy(foundFriend, iHaveFriends(toLink, head));
        //printf("returned from iHaveFriends: %s", foundFriend);

        if (!addBehindFriend(foundFriend, toLink, head))
        {
            //printf("addBehindFriend Failed!");
            while (curr->next != NULL)
            {
                curr = curr->next;
            }
            //curr->next = malloc(sizeof(personNode));
            for (i = 0; i < 3; i++)
            {
                *(head->friends[i]) = toLink->friends[i];
            }
            curr->age = toLink->age;
            strcpy(curr->name, toLink->name);
            curr->next = toLink;
        }
    }
}

char* iHaveFriends(personNode* guest, personNode* head)
{
    personNode* curr = head;
    int i = 0;
    char foundFriend[STR_LEN] = { 0 };

    while (curr->next != NULL)
    {
        for (i = 0; i < 3; i++)
        {
            if (strcmp(curr->name, guest->friends[i]) == 0)
            {
                //printf("\nMATCH: %s, %s, %s\n", foundFriend, guest->friends[i], curr->name);
                strcpy(foundFriend, guest->friends[i]);
            }
            else
            {
                //printf("\nProblem in friend Check!, compared: %s, %s\n", curr->name, guest->friends[i]);
            }
        }
        //printf("\nName: %s", curr->name);
        curr = curr->next;
    }
    //printf("\nReturning: %s", foundFriend);
    return foundFriend;
}

int addBehindFriend(char* friendName, personNode* guest, personNode* head)
{
    //printf("\nrecived: %s, %s\n", friendName, guest->name);
    personNode* curr = head;
    personNode* temp = 0;
    char foundFriend[STR_LEN] = { 0 };
    int flag = 0;
    while (curr->next != NULL)
    {
        if (strcmp(friendName, curr->next->name) == 0)
        {
            flag = 1;
            temp = curr->next;
            curr->next = guest; 
            guest->next = temp;
        }
        else
        {
            //printf("%s, %s\n", friendName, curr->next->name);
        }
        curr = curr->next;
    }
    return flag;
}

void removePersonByName(char name[], personNode* head)
{
    personNode* curr = head;
    int flag = 0;

    while (curr->next != NULL)
    {
        if (strcmp(curr->next->name, name) == 0 && curr->next->next != NULL)
        {
            flag = 1;
            curr->next = curr->next->next;
            break;
        }
        curr = curr->next;
    }

    if (flag)
    {
        printf("%s removed from line", name);
    }
    else
    {
        printf("%s not in line", name);
    }
}

void addToListTop(personNode* VIP, personNode* head)
{
    personNode* tmp = (personNode*)(malloc(sizeof(personNode)));

    tmp->age = head->age;
    strcpy(tmp->name, head->name);
    tmp->next = head->next;

    head->age = VIP->age;
    strcpy(head->name, VIP->name);
    head->next = tmp;

    //VIP->next = tmp;
}

void search(personNode* head, char name[])
{
    personNode* curr = head;
    int flag = 0;

    while (curr->next != NULL)
    {
        if (strcmp(curr->name, name) == 0)
        {
            flag = 1;
            break;
        }
        curr = curr->next;
    }

    if (flag)
    {
        printf("%s found in line", name);
    }
    else
    {
        printf("%s not in line", name);
    }

}

personNode* reverseList(personNode* head)
{
    personNode* curr = head;
    personNode* previous = NULL;
    personNode* next = NULL;

    while (curr != NULL)
    {
        next = curr->next;
        curr->next = previous;
        previous = curr;
        curr = next;
    }

    head = previous;
    printf("Line reversed!");

    return head;
}

2 个答案:

答案 0 :(得分:1)

您的反向功能逻辑似乎很好。你的recursiveprint函数有一个问题,所以在这里,试试这个简单的:

void print(struct personNode *head)
{
    struct personNode *temp = head;
    while(temp != NULL)

    {
        printf("%s  ", temp->name);    
        temp = temp->next;  
    }
}   

答案 1 :(得分:0)

反向功能在本地计算机上无法正常工作。

很难调试它所以我更喜欢重写它。

  

反向功能的工作原理如下:

static personNode * reverse(struct personNode *head)
{
    struct personNode* localHead = NULL;
    struct personNode* temp;
    struct personNode* remainingHead;

    while (head != NULL)
    {
        remainingHead = head->next;

        temp = localHead;
        localHead = head;
        localHead->next = temp;

        head = remainingHead;
    }
    return localHead;
}
  

关于你的递归打印功能

我正在检查头部是否为null,而不是下一个指针。

int recursivePrint(personNode* head)
{
    personNode* curr = head;
    if (head == NULL)
    {
        return 0;
    }
    else
    {
        if (curr != NULL)
        {
            printf("Name: %s, Age: %d \n", curr->name, curr->age);
            recursivePrint(curr->next);
        }
        else
        {
            return 0;
        }
    }
}