Algorithm 气泡排序变体-三个相邻的数字交换

Algorithm 气泡排序变体-三个相邻的数字交换,algorithm,sorting,Algorithm,Sorting,该问题出现在已结束的2018年代码堵塞资格赛中。 (问题2) 问题描述: 标准气泡排序算法的基本操作是检查一对相邻的数字,如果左边的数字大于右边的数字,则反转该对。但是我们的算法检查一组三个相邻的数字,如果最左边的数字大于最右边的数字,它会反转整个组。因为我们的算法是“三重气泡排序”,所以我们把它简称为麻烦排序 我们期待着在特别会议上提出问题 兴趣小组在夏威夷参加分类会议但我们的实习生之一 他刚刚指出了一个问题:麻烦排序可能会这样做 列表排序不正确!考虑列表8、9、7,例如: 我们需要你的帮助做

该问题出现在已结束的2018年代码堵塞资格赛中。
(问题2)

问题描述:

标准气泡排序算法的基本操作是检查一对相邻的数字,如果左边的数字大于右边的数字,则反转该对。但是我们的算法检查一组三个相邻的数字,如果最左边的数字大于最右边的数字,它会反转整个组。因为我们的算法是“三重气泡排序”,所以我们把它简称为麻烦排序

我们期待着在特别会议上提出问题 兴趣小组在夏威夷参加分类会议但我们的实习生之一 他刚刚指出了一个问题:麻烦排序可能会这样做 列表排序不正确!考虑列表8、9、7,例如:

我们需要你的帮助做进一步的研究。给定一个N的列表 整数,确定故障排序是否将成功对 按非降序排列。如果不会,请查找索引 之后第一个排序错误的(从0开始计数) 算法已完成:即第一个大于的值 算法完成时,紧跟其后的值

因此,一种简单的方法是对给定的列表应用故障排序,对列表应用正常排序,然后找到第一个不匹配元素的索引。然而,这将是非常大的N

以下是我的想法: 该算法将第0个索引与第2个索引进行比较,第2个索引与第4个索引进行比较,依此类推。 同样,第1和第3,第3和第5,依此类推

奇数索引处的所有元素将根据奇数索引进行排序。偶数索引元素也是如此。 因此,问题将出现在两个连续的奇偶索引元素之间

我想不出一个不使用O(n^2)方法的方法来解决这个问题


我的方法可行吗?还是有更简单的方法?

你的观察很准确。问题陈述中提出的算法只会比较(和交换)它们之间连续的奇偶元素

如果进一步观察,您可以指出,麻烦排序是一种算法,它可以正确地对数组中的奇数和偶数索引元素进行排序。(即,数组A的奇数索引元素和偶数索引元素是两个单独的数组B和C)

换句话说,故障排序确实正确地对B和C进行排序。这里的问题是奇偶索引元素的数组B和数组C是否可以正确合并。您应该检查对奇数和偶数索引元素进行排序是否足以对整个数组进行排序

此步骤与MergeSort的合并步骤非常相似。唯一的区别是,由于索引是操作的一个限制因素,所以您随时都知道将从哪个数组中选择顶部元素。对于单索引数组a,在B和C的合并步骤中,在每个步骤中,您都应该从B中选择先前未拾取的最小元素,然后从C中选择

因此,基本上,如果您使用诸如mergesort或heapsort之类的算法对B和C进行排序,这需要,
O(NlogN)
,然后按照上一段中描述的方式对它们进行合并,这需要
O(N)
,那么经过故障排序算法处理后,您将得到相同版本的数组A

不同之处在于时间复杂性。虽然故障排序需要
O(N^2)
时间,但上述操作需要
O(NlogN)
时间。一旦你使用了这个数组,如果对于每个连续的索引i,j,
A[i]
保持不变,那么你可以签入
O(N)
time。算法的总体复杂度仍然是
O(NlogN)

下面是Python中的一个代码示例,用于演示我上面描述的算法的伪代码。由于Python数组是0索引的,所以在实现上有几个细微的差异。您可以观察此代码的执行情况


@彼得里瓦兹我不知道我是怎么错过的!谢谢,描述得很优雅。谢谢
def does_trouble_sort_work(A):
    B, C = A[0::2], A[1::2]
    B_sorted = sorted(B)
    C_sorted = sorted(C)
    j = k = 0
    for i in xrange(len(A)):
        if i % 2 == 0:
            A[i] = B_sorted[j]
            j += 1
        else:
            A[i] = C_sorted[k]
            k += 1 

    trouble_sort_works = True
    for i in xrange(1, len(A)):
        if A[i-1] > A[i]:
            trouble_sort_works = False
            break
    return trouble_sort_works