Home > Software design >  Insert data in separate linked lists depending on certain values?
Insert data in separate linked lists depending on certain values?

Time:04-28

I am trying to insert data in a separate linked list based on the value that has been given in the 'Gender' variable.

Please check below how it works with the current implementation and how I am attempting to make it look like.

I think there has to be a change in the insertFirst() and printList() function but I am not sure.

Example of how it works now is shown in the the input below:

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

The expected result should be grouped by gender as follows:

MEN
 Code    Age     Gender                    
  3       3       1
  1       1       1

WOMEN
 Code    Age     Gender
  2       2       0

The code is displayed below:

#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;
}

CodePudding user response:

You're not using your pointer-to list head parameter whatsoever. The very purpose of that argument it to allow updating a specific list. Since you're building two, that parameter should be used for the insertion; not some worthless global head. Printing would likewise involve those two arguments.

Sans a lot of error checking that should still be added, the idea is something like this:

#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;
}

Output (based on your stated input)

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

Also added was a node-creation function and a list cleanup.

  • Related