我正在尝试为圣诞老人制作节目!我的知识有限;我迷失在指针和循环等中,我已经想了几个小时。
我有一组指向单链表的指针。每个数组索引都表示0:0-3,1:4-7,2:8-11,3:11-15的年龄组中的子项列表。
每个孩子都是一个结构,现在每年我想要浏览所有列表,将他们的年龄增加1,如果他们需要更改年龄组,我必须将节点移动到适当的列表中那个年龄组。如果孩子超过15岁,则必须删除该节点。我的代码不完整,因为我是链接列表的新手,我感到很困惑。
我的主要问题是我在浏览列表时对列表进行了更改,所以如果我检查第一个节点并将其删除,我必须再次检查第一个节点,因为现在它是一个新节点,所以我继续检查直到头部没问题,这是正确的方法吗?我不确定我的代码是否有效,我还无法测试它。
我的Santa_Claus.h中的部分:
/*Structure defining a node of the children list*/
struct child {
int cid; /*The identifier of the child.*/
int age; /*The age of the child.*/
int did; /*The identifier of the child.*/
int present_choices[M]; /*The array in which the preferences of the child for presents are stored*/
struct child *next; /* Singly-linked, sorted by id */
};
来自Santa_Claus.c的部分
#define N 4 /*Number of children's age categories*/
struct child *Age_categories[N];
int new_season(void) {
int i;
struct child *childP = NULL;
struct child *prev = NULL;
struct child *childptr = NULL;
int MaxAges[N] = {3,7,11.15};
//Increment Age Loop
for(i = 0; i < N; i++){
childP = Age_categories[i];
while(childP != NULL){
childP->age = childP->age + 1;
childP = childP->next;
}
}
//Remove or Move Loop
for(i = 0; i < N; i++){
childP = Age_categories[i];
//while the first is still > than the max age of this category
while(childP->age > MaxAges[i]){
if(i != (N-1)){
childP->next = Age_categories[i+1];
Age_categories[i+1] = childP;
}else{
Age_categories[i] = childP->next;
}
childP = childP->next;
}
prev = Age_categories[i];
childP = prev->next;
while(childP != Null){
if(childP->age > MaxAges[i]){
if(i != (N-1)){
prev->next = childP->next;
childP->next = Age_categories[i+1];
Age_categories[i+1] = childP;
}else{
Age_categories[i] = childP->next;
}
}
prev = childP;
childP = childP->next;
}
}
return 1;
}
答案 0 :(得分:0)
我的主要问题是我在浏览列表时对列表进行了更改,所以如果我检查第一个节点并将其删除,我必须再次检查第一个节点,因为现在它是一个新节点,所以我继续检查直到头部没问题,这是正确的方法吗?
在适当的位置编辑会咬你的边缘情况。你会遇到头部和尾部节点的问题。如果你移开头部,那么现在跟踪你的头部的任何东西都指向nullspace。
简而言之,你必须要小心。搞砸了很多方法。而对于新手来说,我建议你远离C中的指针。强大,但屁股很痛苦。坚持固定阵列,除非你真的需要这个东西来扩展。
您不需要重新检查头部,只需要检查头部的特殊情况,并进行头部安全编辑。同时检查该组是否为空,并检查尾部通常是好主意。你可以尝试找出一些聪明的东西,以避免这种事情,并有光滑的代码来处理所有...但聪明的代码经常咬你的屁股同样多。
答案 1 :(得分:0)
我的主要问题是我在浏览过程中对列表进行了更改 他们,所以如果我检查第一个节点并将其删除,我必须这样做 再次检查第一个节点,因为它现在是一个新节点,所以我保留 检查直到头部没问题,这是正确的方法吗?
原则上它是正确的方法,但你必须不仅为头部而且为每个列表中的每个节点做到这一点。您的代码并非适用于所有情况,例如:克。
//while the first is still > than the max age of this category
while(childP->age > MaxAges[i]){
if(i != (N-1)){
childP->next = Age_categories[i+1];
Age_categories[i+1] = childP;
}else{
Age_categories[i] = childP->next;
}
childP = childP->next;
}
如果让我们说0岁组的头童已经4岁,那么构成了一个无限循环。
考虑这个正确的代码,这个代码更短,因此错误的机会更少:
// Remove or Move Loop
for (i = 0; i < N; i++)
{
struct child **chPA; // address of pointer to node under check
// for each node in age group i
for (chPA = &Age_categories[i]; childP = *chPA; )
if (childP->age > MaxAges[i])
{
*chPA = childP->next; // remove node from this list
if (i != N-1)
{
struct child **chPA; // address of pointer to node in next group
// find where in next group to insert the aged node
for (chPA = &Age_categories[i+1]; childptr = *chPA;
chPA = &childptr->next)
if (childptr->cid > childP->cid) break;
(*chPA = childP)->next = childptr;
}
else
free(childP); // delete the grown out node
}
else
chPA = &childP->next; // proceed to next node
}
(由于您的代码评论,它根据cid
在下一个更高年龄组中插入一个节点
struct child *next; /* Singly-linked, sorted by id */