我在将链表相应地添加到中间/端时遇到问题
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 之后也是如此