我有一个连续的内存块,其中前N个字节都包含A类型的对象,其余字节包含类型B的元素。例如,我可能有120个A类型的对象,后跟40个类型的对象B.
类型A和类型B都是具有不同大小的结构,但两者都有一个整数成员“index”,这是我想要排序的。基本上我想最终得到一个按索引排序的数组,我目前有一个按数据类型排序的数组。理想情况下,我希望最终按索引排序,然后按类型排序,所以类似
Index==1 elements | Index==2 elements | ... | Index==L elements
Type A | Type B | Type A | Type B | ... | Type A| Type B
到目前为止,我唯一想到的是按索引分别对A类和B类块进行排序,然后使用memcopy来改变周围的东西,使它们看起来像上面一样。有更好的解决方案吗?
答案 0 :(得分:2)
原始阵列是如何设置的?在同一个数组中混合使用不同类型似乎是一个坏主意。你需要将它们放在同一个数组中吗?
如果它们必须位于同一个数组中,您可能需要使用union。像
这样的东西enum myType { A, B };
struct typeA { myType type; int key; ... data ... }
struct typeB { myType type; int key; ... data ... }
union myTypes { typeA myA; typeB myB }
myTypes data[128];
您现在可以使用C库中的qsort功能。
另一个选择是使用指向对象的单独指针数组,然后对辅助数组进行排序。你仍然需要在每个结构的开头有某种类型的字段。
答案 1 :(得分:1)
而不是建议的指针,你可能想要使用由类型和指针组成的结构(后者甚至是两个不同指针的联合)。在这种情况下,您可以轻松区分对象的类型 - 除非它们在同一位置具有ID字段。
假设你有
struct typeA {
int whatever;
int id;
}
struct typeB {
double whatever;
int id;
}
你被咬伤了,我必须按照我的说法去做:
struct typptr {
enum type { typ_A, typ_B } type;
union {
struct typeA * Aptr;
struct typeB * Bptr;
}
}
int getID(struct typptr t)
{
if (t.type == typ_A) {
return (t.Aptr)->id * 2;
} else {
return (t.Bptr)->id * 2 + 1; // have B always sorted after A...
}
}
通过这种方式,您可以轻松地为qsort编写cmp函数,以便对struct typptr
进行排序。
如果类型“形状相似”,例如
struct typeA {
int id;
int whatever;
}
struct typeB {
int id;
double whatever;
}
即。在开始时有id
字段,事情更容易(但我不知道这是否可移植),因为你总是可以转换为其中一个并读出id
字段。所以你只需要一个指针数组就可以省略类型字段。
答案 2 :(得分:0)
您以后的评论中有重要信息 - 这些类型最初并未混合。 如果是这样,你可以单独在每个数组部分上运行一个排序阶段(快速排序或你想要的任何其他方法),然后在两个数组之间进行合并排序的最后阶段(假设你可以节省额外的空间)< / p>
仍然是NlogN + N = NlogN