为什么没有新元素添加到我的链表中?
Why aren't new elements being added to my linked list?
这只是代码的一小段,但我检查并知道一个事实,即所有字符串都很好地保存到“新”元素(在函数 SortedInsert 中),但是“新”元素没有 link到头?
我已经尝试了我能想到的一切,希望我只是遗漏了一些明显的东西。
typedef struct _Info* Position;
typedef struct _Info{
char name[MAX];
char surname[MAX];
Position next;
} Info;
(declaration inside main function:
Info headInfo = {.name = {0}, .surname {0}, .next = NULL};
Position head = &headInfo;
)
int SortedInsert(Position head, char name[], char surname[]){
Position prev = NULL, temp = NULL, new = NULL;
prev = head;
temp = head->next;
new = (Position)malloc(sizeof(Info));
if(!new){
return EXIT_FAILURE;
}
strcpy(new->name, name);
strcpy(new->surname, surname);
new->next = NULL;
if(head->next==NULL){
temp = new;
}
else{
// first sort, by surname
while(strcmp(temp->surname, new->surname) < 0){
prev = temp;
temp = temp->next;
}
// second sort, by name
while(strcmp(temp->name, new->name) < 0){
prev = temp;
temp = temp->next;
}
new->next = prev->next;
prev->next = new;
}
return EXIT_SUCCESS;
}
int PrintList(Position head){
Position temp = NULL;
temp = head->next;
while(temp){
printf("%s ", temp->name);
printf("%s\n", temp->surname);
printf("---\n");
temp = temp->next;
}
return EXIT_SUCCESS;
}
一些问题:
temp = new
不会在列表中插入任何内容。它只是将对新节点的引用复制到局部变量中。分配应该是 head->next
。此外,无需为此创建单独的案例。它可以用你在 else
部分的代码来处理。
检索到的插入点不正确。如果在第一个循环中 strcmp
调用 returns 1(不是 0),那么第二个 while
循环根本不应该迭代:在那种情况下名字是什么并不重要就好像。 temp
的姓已经更大了,所以插入点已经找到了。同样,如果 strcmp
调用 returns 0,则第二个循环应继续验证姓氏在其第二次迭代中是否仍然相同,...等等。而且,这个逻辑可以组合成一个循环。
正确执行没有问题,但仍然:
许多人认为将指针定义为指向结构的指针是不好的做法,您在代码中定期取消引用该指针。请参阅 Is it a good idea to typedef pointers? 的答案了解一些背景知识。所以我会继续使用 Info *
.
创建一个单独的函数来创建和初始化节点。
说“第一类”、“第二类”的评论具有误导性。在评论后面的循环中没有发生 sorting 。列表 已经 排序。接下来的过程只是想按照排序顺序找到插入点。所以评论可以改进。
许多人认为它更好not to cast the value returned by malloc
。
这里是 SortedInsert
函数的更正,以及用于节点创建的分离函数:
Info *createNode(char name[], char surname[]) {
Info *new = malloc(sizeof(*new));
if (new != NULL) {
strcpy(new->name, name);
strcpy(new->surname, surname);
new->next = NULL;
}
return new;
}
int SortedInsert(Info *head, char name[], char surname[]){
Info *new = createNode(name, surname);
if (new == NULL) {
return EXIT_FAILURE;
}
Info *prev = head;
Info *temp = head->next;
// Find insertion spot according to sort order
while (temp != NULL) {
int cmp = strcmp(temp->surname, new->surname);
if (cmp == 0) { // It's a tie. Then use name as discriminator
cmp = strcmp(temp->name, new->name);
}
if (cmp >= 0) { // Found insertion spot
break;
}
prev = temp;
temp = temp->next;
}
new->next = prev->next;
prev->next = new;
return EXIT_SUCCESS;
}
这只是代码的一小段,但我检查并知道一个事实,即所有字符串都很好地保存到“新”元素(在函数 SortedInsert 中),但是“新”元素没有 link到头? 我已经尝试了我能想到的一切,希望我只是遗漏了一些明显的东西。
typedef struct _Info* Position;
typedef struct _Info{
char name[MAX];
char surname[MAX];
Position next;
} Info;
(declaration inside main function:
Info headInfo = {.name = {0}, .surname {0}, .next = NULL};
Position head = &headInfo;
)
int SortedInsert(Position head, char name[], char surname[]){
Position prev = NULL, temp = NULL, new = NULL;
prev = head;
temp = head->next;
new = (Position)malloc(sizeof(Info));
if(!new){
return EXIT_FAILURE;
}
strcpy(new->name, name);
strcpy(new->surname, surname);
new->next = NULL;
if(head->next==NULL){
temp = new;
}
else{
// first sort, by surname
while(strcmp(temp->surname, new->surname) < 0){
prev = temp;
temp = temp->next;
}
// second sort, by name
while(strcmp(temp->name, new->name) < 0){
prev = temp;
temp = temp->next;
}
new->next = prev->next;
prev->next = new;
}
return EXIT_SUCCESS;
}
int PrintList(Position head){
Position temp = NULL;
temp = head->next;
while(temp){
printf("%s ", temp->name);
printf("%s\n", temp->surname);
printf("---\n");
temp = temp->next;
}
return EXIT_SUCCESS;
}
一些问题:
temp = new
不会在列表中插入任何内容。它只是将对新节点的引用复制到局部变量中。分配应该是head->next
。此外,无需为此创建单独的案例。它可以用你在else
部分的代码来处理。检索到的插入点不正确。如果在第一个循环中
strcmp
调用 returns 1(不是 0),那么第二个while
循环根本不应该迭代:在那种情况下名字是什么并不重要就好像。temp
的姓已经更大了,所以插入点已经找到了。同样,如果strcmp
调用 returns 0,则第二个循环应继续验证姓氏在其第二次迭代中是否仍然相同,...等等。而且,这个逻辑可以组合成一个循环。
正确执行没有问题,但仍然:
许多人认为将指针定义为指向结构的指针是不好的做法,您在代码中定期取消引用该指针。请参阅 Is it a good idea to typedef pointers? 的答案了解一些背景知识。所以我会继续使用
Info *
.创建一个单独的函数来创建和初始化节点。
说“第一类”、“第二类”的评论具有误导性。在评论后面的循环中没有发生 sorting 。列表 已经 排序。接下来的过程只是想按照排序顺序找到插入点。所以评论可以改进。
许多人认为它更好not to cast the value returned by
malloc
。
这里是 SortedInsert
函数的更正,以及用于节点创建的分离函数:
Info *createNode(char name[], char surname[]) {
Info *new = malloc(sizeof(*new));
if (new != NULL) {
strcpy(new->name, name);
strcpy(new->surname, surname);
new->next = NULL;
}
return new;
}
int SortedInsert(Info *head, char name[], char surname[]){
Info *new = createNode(name, surname);
if (new == NULL) {
return EXIT_FAILURE;
}
Info *prev = head;
Info *temp = head->next;
// Find insertion spot according to sort order
while (temp != NULL) {
int cmp = strcmp(temp->surname, new->surname);
if (cmp == 0) { // It's a tie. Then use name as discriminator
cmp = strcmp(temp->name, new->name);
}
if (cmp >= 0) { // Found insertion spot
break;
}
prev = temp;
temp = temp->next;
}
new->next = prev->next;
prev->next = new;
return EXIT_SUCCESS;
}