Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用第二个字段排序时,qsort是否保留原始顺序?_C_Qsort - Fatal编程技术网

C 使用第二个字段排序时,qsort是否保留原始顺序?

C 使用第二个字段排序时,qsort是否保留原始顺序?,c,qsort,C,Qsort,假设你有一个城市的名单。与每个城市相关联的是一个州。在创建列表时,您希望按城市名称的字母顺序对其进行排序。列表完成后,您希望按状态对其进行排序。我的问题是,一旦你按州名排序,某个州的城市是否仍按字母顺序排列?或者每个州的城市名单是否需要重新列出?或者有其他方法可以做到这一点吗?不,qsort不要求是一个* 听起来你需要定义一个字典比较器——也就是说,让你的比较器先比较州,然后只在州相等的情况下比较城市 根据C99标准: [7.20.5.2]如果两个元素比较相等,则它们在结果排序数组中的顺序

假设你有一个城市的名单。与每个城市相关联的是一个州。在创建列表时,您希望按城市名称的字母顺序对其进行排序。列表完成后,您希望按状态对其进行排序。我的问题是,一旦你按州名排序,某个州的城市是否仍按字母顺序排列?或者每个州的城市名单是否需要重新列出?或者有其他方法可以做到这一点吗?

不,
qsort
不要求是一个*

听起来你需要定义一个字典比较器——也就是说,让你的比较器先比较州,然后只在州相等的情况下比较城市


  • 根据C99标准:
[7.20.5.2]如果两个元素比较相等,则它们在结果排序数组中的顺序未指定


否,
qsort
不要求是一个*

听起来你需要定义一个字典比较器——也就是说,让你的比较器先比较州,然后只在州相等的情况下比较城市


  • 根据C99标准:
[7.20.5.2]如果两个元素比较相等,则它们在结果排序数组中的顺序未指定

。。。一旦你按州名排序,某个州的城市还会按字母顺序排列吗

否。
qsort()
不是必需的。当元素彼此相等时,顺序可能会改变

还是有其他方法可以做到这一点

避免从比较函数返回0


一种简单的方法是向
geo
类型中添加另一个成员,提供一个规范顺序-最终的连接断路器-可能是原始数组中元素的原始索引。另一种方法是创建指向数组元素的指针数组,并使用指向原始数组的指针进行排序,使用该第二级指针作为平分符

int fcmp_by_state_then_by_index(const void *a, const void *b) {
  const geo *ga = a; // assume array of geo
  const geo *gb = b; 
  int cmp = strcmp(ga->state, gb->state);
  if (cmp) return cmp;
  return (ga->index > gb->index) - (ga->index < gb->index)
}
int fcmp_by_state_然后_by_index(const void*a,const void*b){
const geo*ga=a;//假设geo的数组
常数geo*gb=b;
int cmp=strcmp(ga->state,gb->state);
if(cmp)返回cmp;
返回(ga->index>gb->index)-(ga->indexindex)
}
将地址
a、b
用作最终的连接断路器不一定有效


如果两个元素比较相等,则它们在结果排序数组中的顺序未指定。
C11§7.22.5.2 4

。。。一旦你按州名排序,某个州的城市还会按字母顺序排列吗

否。
qsort()
不是必需的。当元素彼此相等时,顺序可能会改变

还是有其他方法可以做到这一点

避免从比较函数返回0


一种简单的方法是向
geo
类型中添加另一个成员,提供一个规范顺序-最终的连接断路器-可能是原始数组中元素的原始索引。另一种方法是创建指向数组元素的指针数组,并使用指向原始数组的指针进行排序,使用该第二级指针作为平分符

int fcmp_by_state_then_by_index(const void *a, const void *b) {
  const geo *ga = a; // assume array of geo
  const geo *gb = b; 
  int cmp = strcmp(ga->state, gb->state);
  if (cmp) return cmp;
  return (ga->index > gb->index) - (ga->index < gb->index)
}
int fcmp_by_state_然后_by_index(const void*a,const void*b){
const geo*ga=a;//假设geo的数组
常数geo*gb=b;
int cmp=strcmp(ga->state,gb->state);
if(cmp)返回cmp;
返回(ga->index>gb->index)-(ga->indexindex)
}
将地址
a、b
用作最终的连接断路器不一定有效


如果两个元素比较相等,则它们在结果排序数组中的顺序未指定。
C11§7.22.5.2 4


qsort本身不需要稳定,在许多实现中也不需要,特别是在使用快速排序算法实现时

解决此问题的简单方法是:如果您的系统具有
mergesort()
,则此函数确实使用与
qsort()
相同的API实现稳定排序


否则,您可以借用合并排序的实现并使用它。

qsort
本身不需要稳定,在许多实现中也不需要,尤其是在使用快速排序算法实现时

解决此问题的简单方法是:如果您的系统具有
mergesort()
,则此函数确实使用与
qsort()
相同的API实现稳定排序


否则,您可以借用合并排序的实现并使用它。

快速排序可能是稳定的,但需要以特殊的方式实现。所以它和快速排序有一点不同。我们可以称之为qsort_stable:p,实际上,您可以根据需要对任意多的结构成员进行排序。首先处理最高优先级,如果不相等,则返回正的或负的
int
,否则以相同的方式检查下一个成员,依此类推。@Stargateur,尽管它的名称不同,但标准库的
qsort()
函数决不需要通过快速排序算法实现。因此,有关
qsort()
的问题不应被解释为关于快速排序。感谢您在回答中的引用。我想知道为什么当比较器结果为
0
@Stargateur时,
qsort
可以交换两个元素奇怪的是,我看到只有两个元素时交换了两个相等的元素。快速排序可以是稳定的,但需要以特殊的方式实现。所以它和快速排序有一点不同。我们可以称之为qsort_stable:p,实际上,您可以根据需要对任意多的结构成员进行排序。首先处理最高优先级,如果不相等,则返回正的或负的
int
,否则以同样的方式检查下一个成员,依此类推。@Stargateur,尽管名称不同,但标准库的
qsort()