c - 基于变量 C 对链表进行排序

标签 c list sorting linked-list

我正在尝试创建一个调查数据库,其中链接列表根据其变量之一存储调查。目前,当我对调查进行排序时,它仅将节点排序在第一个节点之后(头可能是 999,仍然是第一个节点),并且在添加元素然后显示所有元素时,我偶尔会看到元素的无限打印。

Sample Code:


void addElement(struct listelement** head_ptr)
{
    int data;
    int inputPPS;
    struct listelement *temp;
    struct listelement *newNode;



    if (*head_ptr == NULL)
    {

        addElement_AtStart(head_ptr);

    }

    else

    {

        temp = *head_ptr;
        newNode = (struct listelement*)malloc(sizeof(struct listelement));

        printf("\nPlease enter your PPS number (Number must be unique)\n");
        scanf("%d", &inputPPS);
        if (checkUnique(head_ptr, inputPPS) == 1) {

            newNode->surveyDetails.ppsNo = inputPPS;
            printf("\nPlease enter your first name:");
            scanf("%s", newNode->surveyDetails.fName);
            printf("\nPlease enter your last name:");
            scanf("%s", newNode->surveyDetails.lName);
            //printf("\nEnter email address: ");
            //do email validation
            //scanf("%s", newNode->studentData.email);

            printf("\nEnter current address: ");
            scanf(" %s", newNode->surveyDetails.address);//takes in the next 99 characters until a newline is found

            printf("\nPlease enter your :");
            scanf("%d", &newNode->surveyDetails.age);
            printf("\nPlease enter your yearly salary (as whole number):");
            scanf("%d", &newNode->surveyDetails.income);
            printf("\nHow many cigarrettes do you smoke a day? :");
            scanf("%d", &newNode->surveyDetails.ciggiesSmoked);
            printf("\nHow many units of alcohol do you drink in a day? :");
            scanf("%d", &newNode->surveyDetails.unitsTaken);
            printf("\nHow many time do you exercise every week? :");
            scanf("%d", &newNode->surveyDetails.timesExercised);


            while (temp != NULL)
            {
                if (sortedInsert(&head_ptr, newNode) == 1) {
                    printf("\nSurvey stored successfully\n");
                    break;
                }
                temp = temp->next;

            }

            //printf("\nSurvey didnt work successfully\n");


            //do sorted insert
        }
        else {//if pps is not unique recursively start function again prompting user
            printf("\nWe still value your feedback on this topic! If you believe you have entered your PPS incorrectly you can now try again!");
            addElement(head_ptr);
        }

    }
}

void addElement_AtStart(struct listelement** head_ptr)
{

    struct listelement *newNode;
    int inputPPS;

    newNode = (struct listelement*)malloc(sizeof(struct listelement));

    printf("\nWe will now take details from you for the survery...\n");
    printf("\nPlease enter your PPS number (Number must be unique)\n");
    scanf("%d", &inputPPS);
    if (checkUnique(head_ptr, inputPPS) == 1) {
        newNode->surveyDetails.ppsNo = inputPPS;
        //do unique check
        printf("\nPlease enter your first name:");
        scanf("%s", newNode->surveyDetails.fName);
        printf("\nPlease enter your last name:");
        scanf("%s", newNode->surveyDetails.lName);
        printf("\nEnter email address: ");
        //do email validation
        //scanf("%s", newNode->studentData.email);

        printf("\nEnter current address: ");
        scanf(" %s", newNode->surveyDetails.address);//takes in the next 99 characters until a newline is found

        printf("\nPlease enter your age:");
        scanf("%d", &newNode->surveyDetails.age);
        printf("\nPlease enter your yearly salary (as whole number):");
        scanf("%d", &newNode->surveyDetails.income);
        printf("\nHow many cigarrettes do you smoke a day? :");
        scanf("%d", &newNode->surveyDetails.ciggiesSmoked);
        printf("\nHow many units of alcohol do you drink in a day? :");
        scanf("%d", &newNode->surveyDetails.unitsTaken);
        printf("\nHow many time do you exercise every week? :");
        scanf("%d", &newNode->surveyDetails.timesExercised);
    }
    else {//if pps is not unique recursively start function again prompting user
        printf("\nWe still value your feedback on this topic! If you believe you have entered your PPS incorrectly you can now try again!");
        addElement_AtStart(head_ptr);
    }


    //no sorted insert if file has surveys sorting will be done in addElement

    newNode->next = *head_ptr;

    *head_ptr = newNode; // transfer the address of newNode' to'head'

}
int sortedInsert(struct listelement** head_ref, struct listelement* newNode)
{
    struct listelement* temp;
    /* Special case for the head end */
    if (*head_ref == NULL || (*head_ref)->surveyDetails.ppsNo >= newNode->surveyDetails.ppsNo)
    {
        newNode->next = *head_ref;
        *head_ref = newNode;
        printf("At head");
        return 1;
    }
    else
    {
        /* Locate the node before the point of insertion */
        temp = *head_ref;
        while (temp->next != NULL &&
            temp->next->surveyDetails.ppsNo < newNode->surveyDetails.ppsNo)
        {
            temp = temp->next;
        }
        newNode->next = temp->next;
        temp->next = newNode;
        return 1;
    }
    printf("failed");
}
int checkUnique(struct listelement *head_ptr, int inputPPS) {
    int nodeNum = 0;
    struct listelement *temp;
    temp = head_ptr;



    while (temp != NULL)
    {
        if (nodesAdded == 0) {
            nodesAdded++;
            printf("\n First node so is unique");
            return 1;
        }
        if (temp->surveyDetails.ppsNo== inputPPS )
        {
            printf("\n There is a user in the survey system with this PPS Number.");
            return 0;
        }
        nodeNum++;
        temp = temp->next;
    }
    printf("\nPPS Number is unique. Continuing...\n We will now ask you for your survey details... ");

    nodesAdded++;
    return 1;

}

编辑: 到目前为止,修改了代码,目前我遇到一个问题,即接受变量,但节点未正确分配为头节点,这是在调试中发现的,在添加第二个元素 head_ptr 时会具有奇怪的值(不是进入的)。

void addElement(struct listelement** head_ptr)
{
    int data;
    int inputPPS;
    struct listelement *temp;
    struct listelement *newNode;



    if (*head_ptr == NULL)
    {

        addElement_AtStart(head_ptr);

    }

    else

    {

        temp = *head_ptr;
        newNode = (struct listelement*)malloc(sizeof(struct listelement));

        printf("\nPlease enter your PPS number (Number must be unique)\n");
        scanf("%d", &inputPPS);
        if (checkUnique(&head_ptr, inputPPS) == 1) {

            newNode->surveyDetails.ppsNo = inputPPS;
            printf("\nPlease enter your first name:");
            scanf("%s", newNode->surveyDetails.fName);
            printf("\nPlease enter your last name:");
            scanf("%s", newNode->surveyDetails.lName);
            //printf("\nEnter email address: ");
            //do email validation
            //scanf("%s", newNode->studentData.email);

            printf("\nEnter current address: ");
            scanf(" %s", newNode->surveyDetails.address);//takes in the next 99 characters until a newline is found

            printf("\nPlease enter your :");
            scanf("%d", &newNode->surveyDetails.age);
            printf("\nPlease enter your yearly salary (as whole number):");
            scanf("%d", &newNode->surveyDetails.income);
            printf("\nHow many cigarrettes do you smoke a day? :");
            scanf("%d", &newNode->surveyDetails.ciggiesSmoked);
            printf("\nHow many units of alcohol do you drink in a day? :");
            scanf("%d", &newNode->surveyDetails.unitsTaken);
            printf("\nHow many time do you exercise every week? :");
            scanf("%d", &newNode->surveyDetails.timesExercised);


            while (temp != NULL)
            {
                if (sortedInsert(head_ptr, newNode) == 1) {
                    printf("\nSurvey stored successfully\n");
                    break;
                }
                temp = temp->next;

            }

            //printf("\nSurvey didnt work successfully\n");


            //do sorted insert

        }
        else if (checkUnique(&head_ptr, inputPPS) == 0){//if pps is not unique recursively start function again prompting user
            printf("\nWe still value your feedback on this topic! If you believe you have entered your PPS incorrectly you can now try again!");
            free(newNode);
        }

    }
}

void addElement_AtStart(struct listelement** head_ptr)
{

    struct listelement *newNode;
    int inputPPS;

    newNode = (struct listelement*)malloc(sizeof(struct listelement));

    printf("\nWe will now take details from you for the survery...\n");
    printf("\nPlease enter your PPS number (Number must be unique)\n");
    scanf("%d", &inputPPS);
    if (checkUnique(head_ptr, inputPPS) == 1) {
        newNode->surveyDetails.ppsNo = inputPPS;
        //do unique check
        printf("\nPlease enter your first name:");
        scanf("%s", newNode->surveyDetails.fName);
        printf("\nPlease enter your last name:");
        scanf("%s", newNode->surveyDetails.lName);
        printf("\nEnter email address: ");
        //do email validation
        //scanf("%s", newNode->studentData.email);

        printf("\nEnter current address: ");
        scanf(" %s", newNode->surveyDetails.address);//takes in the next 99 characters until a newline is found

        printf("\nPlease enter your age:");
        scanf("%d", &newNode->surveyDetails.age);
        printf("\nPlease enter your yearly salary (as whole number):");
        scanf("%d", &newNode->surveyDetails.income);
        printf("\nHow many cigarrettes do you smoke a day? :");
        scanf("%d", &newNode->surveyDetails.ciggiesSmoked);
        printf("\nHow many units of alcohol do you drink in a day? :");
        scanf("%d", &newNode->surveyDetails.unitsTaken);
        printf("\nHow many time do you exercise every week? :");
        scanf("%d", &newNode->surveyDetails.timesExercised);
    }
    else {//if pps is not unique recursively start function again prompting user

        printf("\nWe still value your feedback on this topic! If you believe you have entered your PPS incorrectly you can now try again!");
        free(newNode);

    }


    //no sorted insert if file has surveys sorting will be done in addElement

    newNode->next = *head_ptr;

    *head_ptr = newNode; // transfer the address of newNode' to'head'


    free(newNode);
}
int sortedInsert(struct listelement** head_ref, struct listelement* newNode)
{
    struct listelement* temp;
    /* Special case for the head end */
    if (*head_ref == NULL || (*head_ref)->surveyDetails.ppsNo >= newNode->surveyDetails.ppsNo)
    {
        newNode->next = *head_ref;
        *head_ref = newNode;
        printf("At head");
        return 1;
    }
    else
    {
        /* Locate the node before the point of insertion */
        temp = *head_ref;
        while (temp->next != NULL &&
            temp->next->surveyDetails.ppsNo < newNode->surveyDetails.ppsNo)
        {
            temp = temp->next;
        }
        newNode->next = temp->next;
        temp->next = newNode;
        return 1;
    }
    printf("failed");
}
int checkUnique(struct listelement *head_ptr, int inputPPS) {
    int nodeNum = 0;
    struct listelement *temp;
    temp = head_ptr;



    while (temp != NULL)
    {
        if (nodesAdded == 0) {
            nodesAdded++;
            printf("\n First node so is unique");
            return 1;
        }
        if (temp->surveyDetails.ppsNo== inputPPS )
        {
            printf("\n There is a user in the survey system with this PPS Number.");
            return 0;
        }
        nodeNum++;
        temp = temp->next;
    }
    printf("\nPPS Number is unique. Continuing...\n We will now ask you for your survey details... ");

    nodesAdded++;
    return 1;

}

最佳答案

addElement 调用 sortedInsertnewNode 插入到排序位置,但随后它会在之后重新插入 newNode一旦sortedInsert返回,temp。因此,该节点总是紧接在第一个节点之后插入,而之前插入的节点仍然指向该节点,因此链表将无限循环。

如果 checkUnique 失败,您的代码还会泄漏 addElement 中的内存,并且出于同样的原因将在 addElement_AtStart 中插入垃圾节点。您不必要地对将第一个元素插入列表的情况进行特殊处理,并复制了提出问题的所有代码;这是一件非常糟糕的事情。此外,checkUnique 会修改全局状态 (nodesAdded),即使调用代码可能决定不实际插入节点。

编辑:过去我曾因提供工作代码而不是回答问题而被点名。我相信我上面给出的建议确实解决了问题,但是还有其他问题导致它仍然失败。我创建了一个简单的工作示例 here ,所以只有你真的想看的时候才可以看...如果你真的看的话,请仔细研究一下,看看特殊情况和重复情况是如何被消除的。

关于c - 基于变量 C 对链表进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36116022/

相关文章:

c - 为什么在嵌入式系统代码中通过 memcpy 复制结构?

c++ - 如果相似元素已存在,则从 std::list 中移除元素

python以反向模式打印列表的3个第一个元素

algorithm - 不同排序算法的空间复杂度差异

c++ - 在 C++ 中对版本号数组进行排序

arrays - 删除不同索引中具有相同成员的列表

c - 字符串没有填充随机字符(C)?

c - sizeof(char) 和 sizeof(char *) 的区别

代码打印出额外的数据

python - 如何通过列表理解或其他方式将一个列表一分为二