C链表分组值

问题描述

我在C链表中有问题。问题是; 用户将输入一些输入。我们将值添加到链表中。值是id,名称,姓氏。我在这里的工作是将相同的数字分组,然后对找到的数字进行排序。像这样:

用户输入:

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

列表应如下所示:

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

我真的不知道该怎么解决。有人可以帮我解决该算法吗?非常感谢。

解决方法

我假设这是您当前问题的模型。您有一个Employee结构,如下所示:

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

这是您的LinkedList节点的一部分:

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

我认为您应该能够通过维护每个节点的id % 10的频率阵列来做到这一点。然后为您的气泡排序方法稍微自定义逻辑(只需比较frequencyMap[employee.id % 10]而不是比较ID。

以下是示例代码:

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

我是通过main()方法使用它的,例如:

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

这是基于上述代码的示例运行:

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 

更新

从OP的评论中,我注意到不允许更改Node的数据。这是上述基于Node Swap approach的解决方案的略微变体。在这里,我们只需要传递一个Node**,以便在排序过程中更改头部时对其进行更新:

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