二进制插入排序实现 Python

Binary Insertion Sort Implementation Python

在研究算法时,我发现了一个算法,它基本上是一种插入排序,但它在向后移动元素时使用二进制搜索而不是 WHILE 循环语句。

我编写了以下实现代码,它在给定的输入下运行良好。

我的问题是 1) 我的代码有什么改进吗? 2)我仍然不明白为什么尽管使用了二进制搜索它仍然有二次时间。我想我需要帮助来理解这一点。

提前感谢您的宝贵意见:)

A=[3,25,18,41,52,26,38,57,9,49]
def InsertionSort_improved(A):
    for k in range(1,len(A)):
        key = A[k]
        low = 0
        high = k-1
        BinarySearch(A,low,high,key,k)

def BinarySearch(A,low,high,key,k):
    if low<high:
        mid= (low+high)//2
        if A[mid] == key:
            for i in range(k,mid,-1):
                A[i] = A[i-1]
            A[i-1] = key
        elif A[mid] < key:
            BinarySearch(A, mid+1, high, key, k)
        else:
            BinarySearch(A, low, mid, key, k)
    else:
        mid=(low+high)//2
        if A[mid]>key:
            for j in range(k,mid,-1):
                A[j] = A[j-1]
            A[j-1] = key

InsertionSort_improved(A)
print(A)

长话短说:因为这两行。

for j in range(k,mid,-1):
    A[j] = A[j-1]

元素的插入是这样的:

  • 找到插入新元素的位置;
  • 移动大量元素以为新元素腾出空间。

您找到的代码使用二进制搜索来加快第一步,变成 O(log(n)) 而不是 O(n)

但是它仍然需要移动元素,这是通过一个简单的 for-loop 完成的,这需要 O(n) 时间。

注意,对链表而不是数组进行插入排序时,不再需要移位,因此第二步变为O(1)...但是对于链表,二分查找是不可能的, 所以第一步仍然是 O(n).

结论:在数组和链表上,插入排序仍然是二次算法。