【问题标题】:Reordering a list based on a boolean function in C?基于C中的布尔函数重新排序列表?
【发布时间】:2014-12-18 05:46:10
【问题描述】:

给定一个列表和一个布尔函数 f,我如何重新排序该列表,使 f(element) == 1 的所有元素都在前面(这些元素的内部顺序无关紧要)和所有元素f(element) == 0 位于列表的末尾(同样,它们的内部顺序无关紧要)。

我试过了,但它真的很乱,有很多指针。我想知道是否有人知道这样做的“干净”方法?

感谢您的帮助。

【问题讨论】:

  • 列表在哪里?
  • 一些代码会很有用。如果你真的有一个链表(根据你的标签),那么没有结构就不能给你一个好的答案。
  • qsort 不能在任何链表上工作吗?
  • qsort 仅适用于连续的内存块。

标签: c list sorting linked-list


【解决方案1】:

如果你有一个数组,使用 qsort:

#include <stdlib.h>

void qsort(void *base, size_t nmemb, size_t size,
           int (*compar)(const void *, const void *));

这是一个与 qsort 兼容并使用 f 的示例比较器。

int comp(const void* elem1, const void* elem2) {
    int a = f(*((type*)elem1)) ? 1 : 0;
    int b = f(*((type*)elem2)) ? 1 : 0;
    return a - b;
}

如果你有一个链表,那么:

linkedlist* sort(linkedlist* head) {
  linkedlist* newHead = NULL;
  linkedlist* newTail = NULL;
  linkedlist* backHead = NULL;
  linkedlist* backTail = NULL;

  linkedlist* currNode = head;
  while (currNode != NULL) {
    if (f(currNode)) {
      if (newHead == NULL) {
        newHead = newTail = currNode;
      } else {
        newTail.next = currNode;
        newTail = currNode;
      }
    } else {
      if (backHead == NULL) {
        backHead = backTail = currNode;
      } else {
        backTail.next = currNode;
        backTail = currNode;
      }
    }

    currNode = currNode.next;
  }

  if (currTail != NULL) {
     currTail.next = backHead;
  }
  if (backTail != NULL) {
     backTail.next = NULL;
  }
  return currHead != NULL ? currHead : backHead;
}

【讨论】:

  • 我正在尝试根据国际象棋移动是否正在捕获移动对它们进行排序。 f 是游戏和列表(移动)的给定元素的函数。有没有办法使它与比较器兼容?
【解决方案2】:
  1. 找到第一个不符合谓词的节点。
  2. 找到下一个通过谓词的节点。
  3. 交换数据
  4. 继续直到第一次失败后没有节点通过谓词。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-10
    • 2018-09-01
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-13
    相关资源
    最近更新 更多