根据某些值将数据插入单独的链表中?

Insert data in separate linked lists depending on certain values?

我正在尝试根据 'Gender' 变量中给出的值在单独的链表中插入数据。

请在下面查看它如何与当前实施一起工作以及我如何尝试使其看起来像。

我认为 insertFirst()printList() 功能必须有所改变,但我不确定。

下面的输入显示了它现在如何工作的示例:

Insert the code of the person Number 1: 1
Insert the age of the person Number 1: 1
Insert the gender of the person Number 1: 1
Insert the code of the person Number 2: 2
Insert the age of the person Number 2: 2
Insert the gender of the person Number 2: 0
Insert the code of the person Number 3: 3
Insert the age of the person Number 3: 3
Insert the gender of the person Number 3: 1

Code    Age     Gender
3       3       1
2       2       0
1       1       1
   Men
   Women

预期结果应按性别分组如下:

MEN
 Code    Age     Gender                    
  3       3       1
  1       1       1

WOMEN
 Code    Age     Gender
  2       2       0

代码显示如下:

#include <stdio.h>
#include <stdlib.h>

int N;

typedef struct people { /* a struct for people*/
    int code; /* a unique identifier for each person*/
    int age; 
    int gender; 
    struct people *next;
} ppl;

typedef ppl *pppl;        

ppl *head = NULL;
ppl *current = NULL;

//a function to insert nodes
void insertFirst(pppl *q, int code, int age, int gender)
{
    //create a link
    ppl *link = (ppl *)malloc(sizeof(ppl));
    
    link->code = code;
    link->age = age;
    link->gender = gender;
   
    //point it to old first node
    link->next = head;
    
    //point first to new first node
    head = link;
}


          
//display the list
void printList() {
    ppl *ptr = head;
    char myStrings[][23] = { "Code", "Age", "Gender" };
    int i;
    for (i = 0; i <= 3; i++) {
        printf("%s\t", myStrings + i);
    }
    printf("\n");

    //start from the beginnings
    while (ptr != NULL) {
        printf("%d\t\%d\t\%d\n", ptr->code, ptr->age, ptr->gender);
        ptr = ptr->next;
    }    
}

int main() {    
    pppl z1, z2;  
    int i, code1,  age1,  gender1; 

    z1 = NULL;
    z2 = NULL;

    for (i = 1; i <= 3; i++) {
        {
            printf("Insert the code of the person Number %d: ",i);
            fflush(stdin);
            scanf("%d", &code1);         
        }
        printf("Insert the age of the person Number %d: ",i);
        fflush(stdin);
        scanf("%d", &age1);
        {
            printf("Insert the gender of the person Number %d: ",i);
            fflush(stdin);
            scanf("%d", &gender1);
        }
    
        if (gender1 == 1)
            insertFirst(&z1,  code1,  age1,  gender1); // Here it stores in z1 for men
        else
            insertFirst(&z2, code1,  age1,  gender1); // Here it stores in z2 for women
    }
    //print list
    printList();

    printf("   Men \n");
    printList(z1); // I think if that function took parameters it would work like that for z1 and z2
    printf("   Women \n");
    printList(z2);

    return 0;
}

您根本没有使用 pointer-to 列表头参数。该参数的真正目的是允许更新 specific 列表。由于您正在构建两个,因此应该使用该参数进行插入;不是一些毫无价值的全球 head。打印同样会涉及这两个参数。

没有很多仍然应该添加的错误检查,想法是这样的:

#include <stdio.h>
#include <stdlib.h>

typedef struct people
{             /* a struct for people*/
    int code; /* a unique identifier for each person*/
    int age;
    int gender;
    struct people *next;
} ppl;

/*
 * Creates a new ppl record, populating with the
 * provided arguments.
 */
ppl *make_ppl(int code, int age, int gender, ppl *next)
{
    ppl *p = malloc( sizeof *p );
    p->code = code;
    p->age = age;
    p->gender = gender;
    p->next = next;
    return p;
}

/*
 * insert a new node at the head of the provided list.
 * the new node becomes the new head via assignment
 * through the pointer-to-pointer to node.
 */
void insertFirst(ppl **ppHead, int code, int age, int gender)
{
    *ppHead = make_ppl(code, age, gender, *ppHead);
}


/*
 * Display the linked list with the provided preamble
 * title beforehand. note the 'head' pointer is by-value
 * and const, to ensure we do not modify the pointed-to
 * data. Further, we can use that pointer directly to
 * enumerate the list, with no ill effects to the caller.
 */
void printList(const char *title, const ppl *head)
{
    static const char *myStrings[] = {"Code", "Age", "Gender"};
    static const size_t n_strings = sizeof myStrings / sizeof *myStrings;

    puts(title);
    for (size_t i=0; i<n_strings; ++i)
        printf("\t%s", myStrings[i]);
    fputc('\n', stdout);

    // start from the beginning
    while (head != NULL)
    {
        printf("\t%d\t%d\t%d\n", head->code, head->age, head->gender);
        head = head->next;
    }
}

/*
 * Delete a linked list, starting at the head node
 * and following the link chain until exhaustion.
 * When done, the caller's pointer will be null and
 * the list is fully destroyed.
 */
void deleteList(ppl **ppHead)
{
    while (*ppHead)
    {
        ppl *p = *ppHead;
        *ppHead = p->next;
        free(p);
    }
}

int main()
{
    ppl *z1 = NULL;
    ppl *z2 = NULL;
    
    int code1, age1, gender1;

    for (int i = 1; i <= 3; i++)
    {
        printf("Insert the code of the person Number %d: ", i);
        scanf("%d", &code1);

        printf("Insert the age of the person Number %d: ", i);
        scanf("%d", &age1);

        printf("Insert the gender of the person Number %d: ", i);
        scanf("%d", &gender1);

        if (gender1 == 1)
            insertFirst(&z1, code1, age1, gender1); // Here it stores in z1 for men
        else
            insertFirst(&z2, code1, age1, gender1); // Here it stores in z2 for women
    }

    printList("Men", z1);
    printList("Women", z2);

    deleteList(&z1);
    deleteList(&z2);

    return 0;
}

输出(基于您声明的输入)

Men
        Code    Age     Gender
        3       3       1
        1       1       1
Women
        Code    Age     Gender
        2       2       0

还添加了一个 node-creation 函数和一个列表清理。