c - 用 C 读/写多数组数据结构

标签 c arrays

我抽象出了一个需要用 C 语言保存的排序列表。一种方法最适合阅读,另一种方法最适合写作。

WRITE: search KeyNumeric then KeyAlpha and write *Data

Key1 : [ KeyA, *Data1A, KeyB, *Data1B, KeyC, *Data1C ]
Key2 : [ KeyA, *Data2A, KeyB, *Data2B, KeyC, *Data2C ]
Key3 : [ KeyA, *Data3A, KeyB, *Data3B, KeyC, *Data3C ]


READ: search KeyAlpha then KeyNumeric and read *Data

KeyA : [ Key1, *Data1A, Key2, *Data2A, Key3, *Data3A ]
KeyB : [ Key1, *Data1B, Key2, *Data2B, Key3, *Data3B ]
KeyC : [ Key1, *Data1C, Key2, *Data2C, Key3, *Data3C ]

有人知道在内存中表示此数据结构的最有效方法是什么吗?

最佳答案

如果我理解正确的话:

  • 您的数据有一个由数字和某种字母组成的复合键(您没有说明它是字符还是字符串)。
  • 有时您有字母键,需要搜索数字,有时反之亦然(它恰好被读取和(覆盖)写入,但这可能不是重点)。
  • 插入和删除很少见,但需要支持。

我还将假设数据键是稀疏的,因此直接的“[N][A]”数组不适合您。

由于您希望数据进行双重索引,因此我建议您需要某种链接结构:列表或树。

要使用链表来完成此操作,您的 C 结构可能如下所示:

struct stuff {
  int num_key;
  char alpha_key;

  /* The number-first lists.  */
  struct {
    struct stuff *next_num;
    struct stuff *next_alpha;
  } num_list;

  /* The alpha-first links.  */
  struct {
    struct stuff *next_alpha;
    struct stuff *next_num;
  } alpha_list;

  struct data Data;
};

因此,如果您有数据项1A、1B、1C、2A、2B、2C、3A、3B、3C,这些链接的工作方式如下:

  • 1A num_list.next_num 指向 2A
  • 1A num_list.next_alpha 指向 1B
  • 1A num_alpha.next_alpha 指向 1B
  • 1A num_alpha.next_num 指向 2A
  • 2B num_list.next_numNULL
  • 2B num_list.next_alpha 指向 2C
  • 2B num_alpha.next_alphaNULL
  • 2B num_alpha.next_num 指向 3B

因此,用文字来说,num_list.next_num 始终指向具有下一个数字的内容,但第一个 字母可用。同样,alpha_list.next_alpha 始终指向带有下一个字母的内容,但第一个数字可用。如果您不查看辅助列表的头部,则主列表的指针为 NULL,因为您永远不想以这种方式遍历数据,并且在那里维护真正的指针会导致错误,或导致插入或删除时额外的维护。

您可以将其视为两个列表列表:

  • num_list.next_numnum_list.next_alpha 列表的头列表。
  • aplha_list.next_alphaalpha_list.next_num 列表的头列表。

要查找项目,您首先要在主列表之一上移动,num_list.next_numaplha_list.next_alpha,然后向下移动到辅助列表之一,num_list.next_alphanum_alpha.next_num

<小时/>

因此,显然存在一些效率问题:

  • 所有这些小数据 block 的 malloc 效率很低。
  • 访问列表的时间复杂度为 O(n)。

如果您正在处理大量数据,我会做两件事:

  1. 使用某种平衡树而不是平面列表。然后,“列表的头部”就成为“树的根”。

  2. 分配了一个固定大小的struct stuff数组,并使用数组索引作为链接,而不是指针。然后只需维护一个未使用插槽的“空闲列表”即可。如果您的数据超出了数组,则使用 realloc 或分配第二个内存块并记住哪些索引位于哪个 block 中。

关于c - 用 C 读/写多数组数据结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14664438/

相关文章:

c - 给定 4 个点,其中 2 个在不同的半径上。获取圆心

java - 写 "compressed"数组提高IO性能?

c - 数组:越界计算

java - 当长度不同时按大小并排打印 2 个数组

c - 为什么我们需要在 C 并发服务器中为每个客户端创建不同的进程?

c - fscanf 函数在文件处理中的使用

c - 释放 char 指针会将其从我保存的位置删除

c - 如何摆脱 "end of text"

java - 如何设置Object[]的长度

javascript - 对象数组不工作