我一直在阅读,我仍然无法理解链接列表。我的问题是,由于某种原因,当我遍历列表以确定列表中的任何结构是否具有相同的名称或年龄时,它会删除列表,或者当我尝试将新节点添加到列表中时,它也会被删除。
列表是动态的,所以我不会基于任何类型的计数,但用户决定输入多少结构。
任何方向都会受到赞赏。
int add(char* name, char* genderValueString, char* breed, int age, float weight)
{
int result;
int count = 0;
gender curGen = 1;
struct dog *temp = malloc(sizeof(struct dog));
strcpy(temp->name, name);
strcpy(temp->breed, breed);
temp->age = age;
temp->weight = weight;
if (strcmpi(genderValueString, "male") == 0) {
curGen = 0;
}
temp->genderValue = curGen;
if (list == NULL) {
temp->next = list;
list = temp;
result = 1;
}
else {
while (list != NULL) {
if (strcmpi(list->name, name) == 0 && list->age == age) {
result = 0;
}
else {
result = 1;
}
list = list->next;
}
if (result == 1) {
while (list != NULL) {
if (strcmpi(list->name, name) > 0 || list->age > age) {
struct dog *prev = list;
list = temp;
list->next = prev;
}
list = list->next;
}
}
}
return result;
}
答案 0 :(得分:0)
我想你的变量list
是一个全局变量,代表你的列表的头部。
您的代码中的主要问题是您在while循环(list
)中修改list = list->next
,这意味着您正在失去对头部的追踪。
你现在要做的就是让代码工作(也许)就是声明另一个变量,它是头部的副本,你可以安全地修改它。
例如:
struct dog *list_tmp;
...
for (list_tmp = list; list_tmp != NULL; list_tmp = list_tmp->next)
{
if (strcmpi(list->name, name) == 0 && list->age == age) {
result = 0;
}
...
}
为你的两个循环做到这一点。
但是底线,永远不要修改list
,因为它似乎是列表头部的唯一副本;)
答案 1 :(得分:0)
我使用Visual Studio 2013对此进行了测试。您需要跟踪列表的当前头部。我把这个全球命名为doglist
。然后使用局部变量list
在列表中移动。有一个棘手的情况 - 当您在列表的头部之前插入时,您需要将其作为列表的新头部。
struct dog
{
char name[50];
int genderValue;
char breed[50];
int age;
float weight;
struct dog * next;
};
struct dog *doglist = NULL;
int dogadd(char* name, char* genderValueString, char* breed, int age, float weight)
{
struct dog * list = doglist; // save head of list
int count = 0;
int curGen = 1;
struct dog *temp = (dog *)malloc(sizeof(struct dog));
strcpy(temp->name, name);
strcpy(temp->breed, breed);
temp->age = age;
temp->weight = weight;
if (strcmpi(genderValueString, "male") == 0) {
curGen = 0;
}
temp->genderValue = curGen;
if (list == NULL) {
temp->next = list;
doglist = temp;
return 1;
}
while (list != NULL) {
if (strcmpi(list->name, name) == 0 && list->age == age) {
return 0;
}
list = list->next;
}
list = doglist; // restore the head of the list
struct dog * prev = NULL; // keep the previous list node so we can point it to the inserted entry
while (list != NULL) {
int nameCompare = strcmpi(list->name, name);
if ( nameCompare > 0 || (nameCompare == 0 && list->age > age) ) {
temp->next = list;
if (prev != NULL)
prev->next = temp;
// if we are inserting before the current head of the list we need to make this the new head
if (list == doglist)
doglist = temp;
list = temp;
return 1;
}
if (list->next == NULL) {
// Nothing greater than this, so add it to end
list->next = temp;
temp->next = NULL;
return 1;
}
prev = list;
list = list->next;
}
return 0;
}
void main()
{
dogadd("Sybil", "female", "red heeler", 7, 40.1);
dogadd("Pepi", "male", "chihuahua", 5, 3.3);
dogadd("Goliath", "male", "bulldog", 9, 20.5);
dogadd("Harry", "male", "golden retriever", 9, 35.6);
dogadd("ZsaZsa", "female", "poodle", 3, 10.5);
dogadd("Bruce", "male", "german shepherd", 9, 42.7);
dogadd("Sybil", "female", "red heeler", 7, 40.1); // check it isn't added again
struct dog * list = doglist;
while (list != NULL) {
printf("Dog name=%s sex=%d, breed=%s, age=%d, weight=%f\n", list->name, list->genderValue, list->breed, list->age, list->weight);
list = list->next;
}
}