我在将链表相应地添加到中间/端时遇到问题

Posted

技术标签:

【中文标题】我在将链表相应地添加到中间/端时遇到问题【英文标题】:i have a problem adding a linked list into the middle/end accordingly 【发布时间】:2021-08-10 01:23:19 【问题描述】:
/*********************************
* Class: MAGSHIMIM C2            *
* Week:                          *
* Name:                          *
* Credits:                       *
**********************************/

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

#define STR_LEN 20

//Structs
typedef struct personNode

    char name[STR_LEN];
    int age;
    struct personNode* next;
 personNode;

//Functions
void insertPersonQueue(personNode** first, personNode* newNode);
void insertAtEnd(personNode** first, personNode* newNode);
personNode* createPerson(char name[], int age);
int listLength(personNode* curr);
void myFgets(char str[], int n);
void printList();

//Global variables
char* friends[3];

int main(void)

    personNode* first = NULL;
    int userInput = 0;

    while (userInput != 7)
    
        printf("\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", &userInput);
        getchar();

        if (userInput == 2)
        
            printf("Welcome guest!\n");
            char name[STR_LEN];
            int age, listLenVar;

            printf("Enter name: ");
            myFgets(name, STR_LEN);
            printf("Enter age: ");
            scanf("%d", &age);
            getchar();

            personNode* newPerson = createPerson(name, age);
            insertAtEnd(&first, newPerson);

            printf("Enter names of 3 friends:\n");
            for (int i = 0; i < 3; i++)
            
                printf("Friend %d: ", i + 1);
                myFgets(name, STR_LEN);
                friends[i] = (char*)malloc(STR_LEN);
                strcpy(friends[i], name);
            
            insertPersonQueue(&first, newPerson);
            printList(first);
        
        else if (userInput == 1)
        
            int listLenVar = listLength(first);
            printf("%d people in line\n", listLenVar);
            printList(first);
        
        else if (userInput == 3)
        
            printf("NOT WRITTEN YET!\n");
        
        else if (userInput == 4)
        
            printf("NOT WRITTEN YET!\n");
        
        else if (userInput == 5)
        
            printf("NOT WRITTEN YET!\n");
        
        else if (userInput == 6)
        
            printf("NOT WRITTEN YET!\n");
        
    
    getchar();
    return 0;


/**
Function will add a person to the list
input:
newNode - the new person to add to the list
output:
none
*/
void insertAtEnd(personNode** first, personNode* newNode)

    if (!*first)
    
        *first = newNode;
    
    else
    
        personNode* p = *first;
        while (p->next)
        
            p = p->next;
        
        p->next = newNode;
    


/**
Function will print a list of persons
input: the list (the first person)
output:
none
*/
void printList(personNode* first)

    personNode* curr = first;
    while (curr) // when curr == NULL, that is the end of the list, and loop will end (NULL is false)
    
        printf("Name: %s, Age: %d\n", curr->name, curr->age);
        curr = curr->next;
    


/**
Function will count the length of the list using recursion
input:
head of the list
output:
none
*/
int listLength(personNode* curr)

    int ans = 0;
    if (curr)
    
        ans = 1 + listLength(curr->next);
    
    return ans;


/**
Function will create a person
input:
person name and his age
output:
the person updated with correct information
*/
personNode* createPerson(char name[], int age)

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

    strncpy(newPerson->name, name, STR_LEN);
    newPerson->age = age;
    newPerson->next = NULL;

    return newPerson;


/**
Function will insert a person to the linked lists
if their friend is in the list then it will add that person right before there friend
if he has more than 2 friends that are in the lists it will add him behind the one that is the nearest to the first
input:
double pointer to the first list in the linked lists (the head)
and a pointer to the new list that wanted to be inserted
output:
none
*/
void insertPersonQueue(personNode** first, personNode* newNode)

    int fOne = 0, fTwo = 0, fThree = 0, pos = 0;
    if (!*first)
    
        *first = newNode;
    
    else
    
        personNode* p = *first;
        personNode* loopP = *first;
        while (p)
        
            if (strcmp(p->name, friends[0]) == 0)
            
                fOne = 1;
                fOne += pos;
            
            else if (strcmp(p->name, friends[1]) == 0)
            
                fTwo = 1;
                fTwo += pos;
            
            else if (strcmp(p->name, friends[2]) == 0)
            
                fThree = 1;
                fThree += pos;
            
            p = p->next;
            pos++;
        

        if (fOne >= fTwo && fOne >= fThree && fOne > 0)
        
            for (int i = 0; i < fOne - 1; i++)
            
                loopP = loopP->next;
            

            printf("new next changed to - %s\nloopP next changed to %s\n", loopP->next->name, newNode->name);
            newNode->next = loopP->next;
            loopP->next = newNode;
            
        
    


/*
Function will perform the fgets command and also remove the newline
that might be at the end of the string - a known issue with fgets.
input: the buffer to read into, the number of chars to read
*/
void myFgets(char* str, int n)

    fgets(str, n, stdin);
    str[strcspn(str, "\n")] = 0;

我在制作函数“insertPersonQueue”第 182 行时遇到问题。

此函数接收一个新的人员列表(作为结构)并将其添加到链接列表中。

现在它的工作原理是,如果他们的朋友在列表中,那么它将将该人添加到该朋友之前。

如果他有超过 2 个朋友在列表中,它会将他添加到最接近第一个列表的朋友后面。

在打印过程中它做得对,但它只是永远打印它。

我想我知道为什么会发生这种情况,这是因为在第 213 行中,我在链接列表中进行了更改 向右移动 1 的列表 下一个指向已添加的新列表 这就是为什么程序只循环这两个列表的原因。

因为新列表的“下一个”如果指向向右移动 1 的列表,并且该列表“下一个”指向新列表。

这就是为什么在第 127 行的函数“printList”中它只是循环通过这两个列表。

我试图修复它,但它对我不起作用。

在主函数第 44 行到第 69 行中,输入了 3 个朋友,年龄和姓名。

输出:


2

欢迎客人!

输入姓名:杰克

输入年龄:15

输入 3 个朋友的名字:

朋友 1:ksi

朋友 2:测试

朋友 3:testtt

姓名:杰克,年龄:15

2 欢迎客人!

输入姓名:洛根

输入年龄:18

输入 3 个朋友的名字:

朋友 1:乔治

朋友 2:testt

朋友 3: tteestrt

姓名:杰克,年龄:15

姓名:洛根,年龄:18

2 欢迎客人!

输入姓名:莫兰

输入年龄:16

输入 3 个朋友的名字:

朋友 1:杰克

朋友 2:无

朋友 3:nlolloadsadd

姓名:杰克,年龄:15

姓名:莫兰,年龄:16

姓名:洛根,年龄:18

姓名:莫兰,年龄:16

姓名:洛根,年龄:18

姓名:莫兰,年龄:16

姓名:洛根,年龄:18

姓名:莫兰,年龄:16

姓名:洛根,年龄:18

姓名:莫兰,年龄:16

姓名:洛根,年龄:18

姓名:莫兰,年龄:16

姓名:洛根,年龄:18

姓名:莫兰,年龄:16

姓名:洛根,年龄:18

永远循环!


预期输出:

姓名:杰克,年龄:15

姓名:莫兰,年龄:16

姓名:洛根,年龄:18

永远不要循环!

【问题讨论】:

一个例子将讲述超过 100 行的文字描述。所以添加两个场景的输入。还要加上实际输出和预期输出 确定!谢谢你告诉我 请澄清:0 个朋友 -> “在 ?? 插入新人”,1 个朋友 -> “在“插入新人”,2 个朋友 -> “在 ?? 插入新人”,3 个朋友->“在列表中的第一个朋友之后插入新人” 如果此人有超过 1 个朋友的名字在链表中,则此人不会被放置在行尾,他将被放置在距离第一个链表最近的朋友后面(列表的头部)如果他输入的名字不在列表中,那么他将被放置在行尾 我去看看……哦,朋友们可以同名吗……“bill”、“joe”、“bill” 【参考方案1】:

要求(根据聊天中的讨论)是:

0 friends --> Insert new person at the end of the list
1, 2 or 3 friends --> Insert new person after first friend

您的insertPersonQueue 中的逻辑是错误的,原因有几个。一个例子是它只在friend[0] 上运行。另一个是它不处理case 0好友。

一般来说,您的实现过于复杂。它可以更容易地解决。

简单地迭代(即遍历)列表并检查当前节点是否是新人的朋友。如果答案是“是”,则在当前节点之后插入新人并从函数返回。如果您到达列表的末尾(即未找到朋友),请在末尾插入新的人。

试试这个代码:

void insertPersonQueue(personNode** first, personNode* newNode)

    if (*first == NULL)
    
        // Empty list, i.e. add as head of list
        *first = newNode;
        return;
    

    personNode* p = *first;
    personNode* prev = NULL;
    while (p)
    
        if ((strcmp(p->name, friends[0]) == 0) ||
            (strcmp(p->name, friends[1]) == 0) ||
            (strcmp(p->name, friends[2]) == 0))
        
            // Found the first friend, i.e. insert new person AFTER this person
            newNode->next = p->next;
            p->next = newNode;
            return;
        
        prev = p;
        p = p->next;
    

    // No friends found, i.e. add to the end
    prev->next = newNode;    

【讨论】:

也许调整问题以反映这一新要求也会很好 @dreamcrash 同意... OP 应该更新问题以明确要求。目前我正在等待 OP 批准这是 OP 想要的。

以上是关于我在将链表相应地添加到中间/端时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

我在将字符串从 .txt 文件添加到列表时遇到问题,即使在尝试使用 .append 之后也是如此

我在将 Css 文件链接到 Django 模板时遇到问题

Lumen:将中间件添加到打包定义的路由中

我在将 klaviyo 与 laravel 集成时遇到了这个错误

将链表从 C 传递到 C++

为啥我在将 MERN 部署到 Heroku 期间错误地收到文件丢失错误?