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

时间:2016-03-20 15:58:19

标签: 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;

}

1 个答案:

答案 0 :(得分:0)

addElement调用sortedInsertnewNode插入已排序的位置,但在newNode返回temp后重新插入sortedInsert 。因此,节点总是在第一个节点之后立即插入,而之前插入的节点仍将指向它,因此列表将循环不停。

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

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