简体   繁体   中英

C linked lists grouping values

I have a problem in C linked lists. The problem is; User will enter some inputs. And we gonna add to linked list the values. Values are, id,name,surname. My job here grouping the same ones digit and sorting them most found. Like this:

User entered:

47 Max Clark
37 Amy Jhinar
89 Bob Lewis
25 Jackson Adams
29 Jackie Kitcher
27 Karen Robinson

The list should be like this:

47 Max Clark => 37 Amy Jhinar => 27 Karen Robinson => 89 Bob Lewis => 29 Jackie Kitcher => 25 Jackson Adams

I really don't know how to figure it out. Can someone help me with the algorithm? Thanks a lot.

I am assuming this is model for your current problem. You have an Employee struct like this:

typedef struct Employee {
    int id;
    char name[100];
    char surname[100];
} Employee;

Which is a part of your LinkedList node:

typedef struct Node {
    Employee employee;
    struct Node *next;
} Node;

I think you should be able to do it by maintaining an array of frequencies of each Node's id % 10 . Then slightly customizing logic for your bubble sort method(Just need to compare frequencyMap[employee.id % 10] rather than just comparing ids.

Here is sample code:

void reorderBasedOnFrequency(Node *head) {
    int frequencyMap[10] = { 0 };

    // Build array of frequencies for id mod 10`
    Node *currentNode = head;
    while (currentNode != NULL) {
        frequencyMap[currentNode->employee.id % 10]++;
        currentNode = currentNode->next;
    }

    // Perform Standard Bubble Sort
    bool swapped = true;
    Node *ptr1;
    Node *lptr = NULL;

    do {
        swapped = false;
        ptr1 = head;

        while (ptr1->next != lptr) {
            // Check for frequencies while sorting
            if (frequencyMap[(ptr1)->employee.id % 10] < frequencyMap[(ptr1->next)->employee.id % 10]) {
                // Swap
                swap(ptr1, ptr1->next);
                swapped = true;
            }
            ptr1 = ptr1->next;
        }
        lptr = ptr1;
    } while (swapped);
}

void swap(struct Node *a, struct Node *b) { 
    Employee temp = a->employee; 
    a->employee = b->employee; 
    b->employee = temp; 
} 

I used it from my main() method like this:

int main() {
    Employee employees[6] = { {47, "Max", "Clark"}, {37, "Amy", "Jhinar"}, {89, "Bob", "Davis"}, {25, "Jackson", "Adams"},
      {29, "Jackie", "Kitcher"},{27, "Karen", "Robinson"}};

    Node *head = NULL;
    Node *tail = NULL;
    for (int i = 0; i < 6; i++) {
        Node *newNode = (Node *)malloc(sizeof(Node));
        newNode->employee = employees[i];
        newNode->next = NULL;
        if (i == 0) {
            head = newNode;
            tail = newNode;
        } else {
            tail->next = newNode;
            tail = newNode;
        }
    }

    printf("Initial List: \n");
    printList(head);
    reorderBasedOnFrequency(head);
    printf("After Sorting: \n");
    printList(head);
}

Here is a sample run based on above code:

src : $ gcc linkedlistsortmodulo.c 
src : $ ./a.out 
Initial List: 
47 Max Clark  => 37 Amy Jhinar  => 89 Bob Davis  => 25 Jackson Adams  => 29 Jackie Kitcher  => 27 Karen Robinson 
After Sorting: 
47 Max Clark  => 37 Amy Jhinar  => 27 Karen Robinson  => 89 Bob Davis  => 29 Jackie Kitcher  => 25 Jackson Adams 

Update:

From comments by OP, I noticed that changing Node's data is not allowed. Here is a slight variant of above solution based on the Node Swap approach . Here we just need to pass a Node** so that head gets updated if it's changed during sorting process:

void reorderBasedOnFrequency(Node **head) {
  int frequencyMap[10] = { 0 };
    
  // Build array of frequencies for id mod 10`
  Node *currentNode = *head;
  int nCount = 0;
  while (currentNode != NULL) {
    frequencyMap[currentNode->employee.id % 10]++;
    currentNode = currentNode->next;
    nCount++;
  }

  // Perform Standard Bubble Sort
  bool swapped = true;
  Node **h;

  for (int i = 0; i <= nCount && swapped; i++) {
    h = head;
    swapped = false;
    for (int j = 0; j < nCount - i - 1; j++) {
      Node *p1 = *h;
      Node *p2 = p1->next;
      // Check for frequencies while sorting
      if (frequencyMap[p1->employee.id % 10] < frequencyMap[p2->employee.id % 10]) {
        // Swap
        *h = swap(p1, p2);
        swapped = true;
      }

      h = &(*h)->next;
    }
  }
}

Node* swap(struct Node *a, struct Node *b) { 
  Node *tmp = b->next;
  b->next = a;
  a->next = tmp;
  return b;
} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM