C++ 使用三位数比较器进行排序

C++ 使用三位数比较器进行排序,c++,algorithm,sorting,C++,Algorithm,Sorting,我有一个大小为n的数组等待排序。但与普通的排序问题不同,我必须使用一个特定的比较器,它接收三个数字并告诉三个数字的最大值和最小值。我的目标是在完全排序数组之前尽可能少地使用比较器。我可以使用什么策略 谢谢你的帮助 嗯,我想出了一个主意 让我们记住快速排序的工作原理: 首先,我们定位一种中间值(如果你太懒了,就选择(a[0]+a[N-1])/2) 然后,我们划分一个数组 在小于或大于中间值的条件下增加两倍 最后,我们在两个子阵列中的每一个子阵列上递归地运行该算法 使用比较器,您可以通过一次处理

我有一个大小为n的数组等待排序。但与普通的排序问题不同,我必须使用一个特定的比较器,它接收三个数字并告诉三个数字的最大值和最小值。我的目标是在完全排序数组之前尽可能少地使用比较器。我可以使用什么策略


谢谢你的帮助

嗯,我想出了一个主意

让我们记住快速排序的工作原理:

  • 首先,我们定位一种中间值(如果你太懒了,就选择
    (a[0]+a[N-1])/2
  • 然后,我们划分一个数组 在小于或大于中间值的条件下增加两倍
  • 最后,我们在两个子阵列中的每一个子阵列上递归地运行该算法
使用比较器,您可以通过一次处理两个值两次加速第二阶段:

  • 比较(中位数,a[2*i],a[2*i+1])
  • 如果“最小”为“中值”,则两者都较大,并转到右侧子阵列
  • 如果max是median,则两者都较小,并转到左侧子阵列
  • 如果两者都不是中间值,则最小值向左,最大值向右

之后,像往常一样运行算法的递归部分。

因为三向比较器可以通过对普通比较器的三次调用来实现,这意味着我们无法将任何普通排序算法的改进幅度提高到3倍以上。一个更仔细的论证表明了这一点,因为每一个三方比较都给我们提供了log₂ 6.≈ 2.585比特的信息,我们不能再提高了。直观地说,当使用普通比较器进行排序时,您可能会比较
a嗯,我有一个绝妙的想法。使用4路mergesort和loser树进行优化,使用比较器的次数可以减少到0.5nlog以下₂n、 据我粗略估计。

你尝试过什么策略?:)我没有弄清楚如何充分利用一次比较所提供的信息(理论上,它应该将我的比较次数除以三)。此外,算法的性能应该是一致的,因此最坏的情况仍然是O(nlogn)。我在考虑快速排序或合并排序。所以你输入三个数字,然后返回两个?您应该如何确定哪一个输入是中间数字(不需要再次将两个输出与三个输入进行比较)?(例如,如果你询问的算法与C++无关),例如,如果我放在1,2,3,比较器告诉我最大值和最小值的索引[a],a(2),a[3 ]。假设a[1]是最大值,a[2]是最小值,那么a[3]是中间值。看起来不错。但我认为在最坏的情况下有可能衰变为O(n^2)。好吧,基本的快速排序在最坏的情况下是O(n^2)。将数组中随机N个元素的平均值作为中位数可以解决这个问题,但这仍然是可能的。你们不能真的违背快速排序的理论。至少,建议的方法并没有真正改变一个原始的算法,哪怕是一点点。而且,大多数编译器和语言都接受快速排序作为默认排序,因此使用它应该足够安全。检查“if min is median”似乎需要使用
=
,这可能不可用。假设比较器是我们所有的,我想知道这个练习是否应该解决。不,最小和最大指针只携带索引,所以这个方法有效。