C-根据值移动或删除多个节点



我正在为圣诞老人制作一个程序!我的知识是有限的;我迷失在指针和循环等方面,我已经想了几个小时了。

我有一个指向单链表的指针数组。每个数组索引指示0:0-3、1:4-7、2:8-11、3:11-15年龄组的儿童列表。

每个孩子都是一个结构,现在每年之后,我都想浏览所有列表,将他们的年龄增加1,如果他们需要更改年龄组,我必须将节点移动到包含该年龄组的适当列表中。如果子节点超过15岁,则必须删除该节点。我的代码是不完整的,因为我是链接列表的新手,我感到困惑。

我的主要问题是,我在浏览列表时会对列表进行更改,所以如果我检查第一个节点并将其删除,我必须再次检查第一个结点,因为现在它是一个新的结点,所以我一直检查,直到Head正常,这是正确的方法吗?我不确定我的代码是否有效,我还不能测试它。

我的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;
}

我的主要问题是,我在浏览列表时会对列表进行更改,所以如果我检查第一个节点并将其删除,我必须再次检查第一个结点,因为现在它是一个新的结点,所以我一直检查,直到Head正常,这是正确的方法吗?

在位编辑会在边缘情况下咬到你。头部和尾部节点会出现问题。如果你移除了头部,那么任何跟踪你头部的东西现在都指向空空间。

简而言之,你只需要小心。有很多方法可以把它搞砸。对于新手来说,我建议你远离C中的指针。强大,但很痛苦。除非你真的需要这个东西来扩展,否则坚持固定的数组。

你不需要重新检查头部,只需要有一个特殊的案例来检查头部,并进行头部安全编辑。此外,检查集合是否为空,以及检查尾部通常是个好主意。你可以尝试想出一些聪明的方法来避免这种事情,并拥有处理这一切的平滑代码。。。但是,聪明的代码往往同样会让你头疼。

我的主要问题是在浏览时对列表进行更改因此,如果我检查第一个节点并将其删除,我必须再次检查第一个节点,因为现在它是一个新节点,所以我保留检查,直到头部正常,这是正确的方法吗?

原则上,这是正确的方法,但不仅要对头部,还要对每个列表中的每个节点都这样做。您的代码并非在所有情况下都有效,例如

        //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 */

相关内容

  • 没有找到相关文章

最新更新