实现插入排序时,可以使用二进制搜索来定位要插入元素i的数组的第一个i-1元素内的位置。
这会如何影响所需的比较次数?如何使用这样的二进制搜索影响Insertion Sort的渐近运行时间?
我很确定这会减少比较次数,但我不确定原因。
答案 0 :(得分:19)
直接来自维基百科:
如果比较成本超过掉期成本,就像这样 例如,通过引用或人工存储的字符串键 交互(例如选择并排显示的一对), 然后使用二进制插入排序可以产生更好的性能的二进制 插入排序使用二进制搜索来确定正确 插入新元素的位置,因此执行⌈log2(n)⌉ 最坏情况下的比较,即O(n log n)。该算法为 由于这个原因,整体的运行时间平均为O(n2) 每次插入都需要一系列交换。
来源:
http://en.wikipedia.org/wiki/Insertion_sort#Variants
以下是一个例子:
http://jeffreystedfast.blogspot.com/2007/02/binary-insertion-sort.html
我很确定这会减少比较次数,但是我 不完全确定原因。
好吧,如果你已经知道插入排序和二进制搜索,那么它非常直接。在插入排序中插入一个片段时,必须与之前的所有片段进行比较。假设您要将此[2]移动到正确的位置,在找到正确的位置之前,您必须比较7件。
[1] [3] [3] [3] [4] [4] [5] - > [2] < - [11] [0] [50] [47]
但是,如果你在中间点开始比较(比如二分搜索),那么你只会比较4件!你可以这样做,因为你知道左边的部分已经按顺序排列了(如果部分是有序的话,你只能进行二进制搜索!)。
现在想象一下,如果你有数千件(甚至数百万件),这将为你节省大量时间。我希望这有帮助。 | = ^)
答案 1 :(得分:6)
如果您有有效的二进制搜索的良好数据结构,则不太可能具有O(log n)插入时间。相反,在任意位置快速插入的良好数据结构不太可能支持二进制搜索。
要实现具有插入排序的最佳比较搜索的O(n log n)性能,需要O(log n)二分搜索和O(log n)任意插入。
答案 2 :(得分:1)
假设数组已排序(用于执行二进制搜索),它不会减少任何比较,因为内部循环在1比较后立即结束(因为前一个元素较小)。通常,插入排序中的比较数量最多为反转次数加上数组大小 - 1.
由于已排序数组中的反转次数为0,因此已排序数组中的最大比较次数为N-1。
答案 3 :(得分:0)
二进制插入排序-采用此数组=> {4,5,3,2,1}
现在在主循环内,假设我们处于第三个元素。现在,使用Binary Search,我们将知道在4之前插入3的位置。
二进制搜索使用O(Logn)比较,这是一个改进,但我们仍然需要在正确的位置插入3。为此,我们需要将3与5交换,然后与4交换。
由于插入所花费的时间与没有二进制搜索所花费的时间相同,因此最坏情况的复杂度仍然为O(n ^ 2)。 我希望这会有所帮助。
答案 4 :(得分:0)
为进行比较,我们记录了n次时间,而交换次数将为n次。 对于最坏情况下的n个元素,n *(log n + n)的阶数为n ^ 2。