我编写了以下程序来存储来自地址格式文件的输入,并按照存储在节点中的城市名称的字母顺序对链表进行排序。样本输入如下:
Titus \n
Kollman \n
1522 Foggy Grove Loop \n
Wildcat NC 27507 \n
(252) 644-5477 \n
...等
我的代码当前正确地创建了所有条目的未排序链接列表,并且我已经编写了一个排序函数来按字母顺序对列表进行排序。当我尝试对列表进行排序时,我的代码只是连续运行而没有输出(卡住),我找不到排序算法的任何问题。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* make node structure to store the data in */
struct entry {
char fname[64];
char lname[64];
char city[64];
char address[64];
char cityandstate[64];
char numb[64];
struct entry* next;
};
/* function to add entry that will be used in sort*/
void addEntryForSort(struct entry* list, struct entry* x){
struct entry* newNode = (struct entry*) malloc(sizeof(struct entry));
memcpy(newNode,x,sizeof(struct entry));
newNode->next = NULL;
while (list->next != NULL){
list = list->next;
}
list->next = newNode;
}
/*function to find the minimum (alpha)of a linked list */
struct entry* findMin(struct entry* begin){
struct entry* curr = begin;
struct entry* min = curr;
curr = curr->next;
while (curr != NULL){
if (strcmp(curr->city,min->city) < 0){
min = curr;
}
else if (strcmp(curr->city,min->city))
curr = curr->next;
}
return min;
}
/*sort function (attempt)*/
struct entry* sort(struct entry* top){
struct entry* sorted = (struct entry*) malloc(sizeof(struct entry));
struct entry* min = findMin(top);
struct entry* curr = top;
while (curr->next != NULL){
if (top == min){
addEntryForSort(sorted,min);
top = top->next;
min = findMin(top);
curr = top;
}
if (curr->next == min){
addEntryForSort(sorted,min);
curr->next = curr->next->next;
min = findMin(top);
curr = top;
}
else {
curr = curr->next;
}
}
addEntryForSort(sorted,top);
addEntryForSort(sorted,curr);
return sorted;
}
int main() {
struct entry* head = (struct entry*) malloc(sizeof(struct entry));
char x[64];
fgets(x,64,stdin);
strcpy(head->fname,x);
strtok(head->fname,"\n");
fgets(x,64,stdin);
strcpy(head->lname,x);
strtok(head->lname,"\n");
fgets(x,64,stdin);
strcpy(head->address,x);
strtok(head->address,"\n");
fgets(x,64,stdin);
strcpy(head->cityandstate,x);
strtok(head->cityandstate,"\n");
strncpy(head->city,head->cityandstate,strlen(head->cityandstate)-10);
fgets(x,64,stdin);
strcpy(head->numb,x);
strtok(head->numb,"\n");
fgets(x,64,stdin);
int line = 7;
struct entry* curr = (struct entry*) malloc(sizeof(struct entry));
struct entry* prev = head;
head->next = curr;
while (fgets(x,64,stdin) != NULL) {
switch (line % 6){
case 1:
strcpy(curr->fname,x);
strtok(curr->fname,"\n");
break;
case 2:
strcpy(curr->lname,x);
strtok(curr->lname,"\n");
break;
case 3:
strcpy(curr->address,x);
strtok(curr->address,"\n");
break;
case 4:
strcpy(curr->cityandstate,x);
strtok(curr->cityandstate,"\n");
strncpy(curr->city,curr->cityandstate,strlen(curr->cityandstate)-10);
if (strcmp(curr->city,"Old Roach MO 6") == 0){
strcpy(curr->city,"Old Roach");
}
break;
case 5:
strcpy(curr->numb,x);
strtok(curr->numb,"\n");
break;
case 0:
curr->next = (struct entry*) malloc(sizeof(struct entry));
prev = curr;
curr = curr->next;
break;
}
line++;
}
curr=sort(head);
while (curr!= NULL){
printf("%s %s %s\n",curr->fname,curr->lname,curr->city);
curr = curr->next;
}
}
答案 0 :(得分:0)
我还不确定这个问题(还没有测试过您的代码),但请考虑这部分代码:
while (curr != NULL){
if (strcmp(curr->city,min->city) < 0){
min = curr;
/* curr gets stuck here and doesn't move */
}
else if (strcmp(curr->city,min->city))
/* curr gets stuck if curr->city is equal to min->city */
curr = curr->next;
}
将其更改为以下内容并报告您是否仍然面临问题。
while (curr != NULL) {
if (strcmp(curr->city, min->city) < 0) min = curr;
curr = curr->next; }
答案 1 :(得分:0)
此代码中存在许多问题。
首先,你永远不会初始化你的结构,并且malloc也不应该这样做,因此next
成员可能不为null,使得以下所有代码都失败。你应该写:
struct entry* head = (struct entry*) malloc(sizeof(struct entry));
head->next = NULL; /* ensure next is correctly initialized */
和下一个:
struct entry* curr = (struct entry*) malloc(sizeof(struct entry));
curr->next = NULL; /* ensure next is correctly initialized */
您使用strncpy初始化city
字段。但strncpy不会添加终止空值,使您的字段无终止。你应该写:
strncpy(curr->city,curr->cityandstate,strlen(curr->cityandstate)-10);
curr->city[strlen(curr->cityandstate)-10] = '\0';
(与第一条记录的head
相同)。
在findMin
中,如果两个记录比较相等,则会因为您没有调用curr = curr->next
而停留在那里。它应该是:
/*function to find the maximum (alpha)of a linked list */
struct entry* findMax(struct entry* curr){
struct entry* min = curr;
while (curr != NULL){
if (strcmp(curr->city,min->city) > 0){
min = curr;
}
curr = curr->next;
}
return min;
}
我获得最大值而不是最小值,因为要使用简单的冒泡排序对单个链接列表进行排序,最简单的方法是将其排序到位,从列表中取出最大元素并将其放在第一位结果列表。此外,这可以避免分配新结构,因为如果您不想泄漏内存,则必须释放每个已分配的块。 sort
函数可能变为:
/*sort function (attempt)*/
struct entry* sort(struct entry* top){
struct entry* sorted = NULL;
while (top != NULL) {
struct entry* max = findMax(top);
if (max == top) { /* if max is first, simply increment top */
top = top->next;
}
else { /* else make prev->next = max->next to remove max from the list */
struct entry *curr = top;
while (curr->next != min) curr = curr->next;
curr->next = min->next;
}
/* and put current max in first place of the sorted list */
max->next = sorted;
sorted = max;
}
return sorted;
}
最后,你应该通过在main的末尾添加所有已分配的内存块来释放:
/* free all elements of the linked list */
while(head != NULL) {
curr = head->next;
free(head);
head = curr;
}
return 0; /* never return random value to environment */
但是如果你想进行认真的编程,你还应该:
fgets
不应返回NULL,缓冲区应该有\n
作为最后一个字符