Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/336.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
Python 二进制插入排序与快速排序_Python_Arrays_Algorithm_Performance_Sorting - Fatal编程技术网

Python 二进制插入排序与快速排序

Python 二进制插入排序与快速排序,python,arrays,algorithm,performance,sorting,Python,Arrays,Algorithm,Performance,Sorting,我在研究不同的排序算法及其性能(),然后我尝试自己实现一些排序算法。我还想改进它们,因此,在编写插入排序的代码时,我想为什么不使用二进制搜索,因为数组的第一部分已经排序,为了摆脱交换,可以使用额外的数组。代码可在以下位置找到: 然后我像往常一样实现了快速排序(): 因此,它基本上运行给定的sort函数,并打印排序数组所需的时间。所以我至少运行了10次这段代码,每次二进制插入排序几乎快了9倍(9s>1s)。但我认为快速排序是最快的。。。如果我比较这两种排序算法,我会说二进制插入排序更好,尽管它需要

我在研究不同的排序算法及其性能(),然后我尝试自己实现一些排序算法。我还想改进它们,因此,在编写插入排序的代码时,我想为什么不使用二进制搜索,因为数组的第一部分已经排序,为了摆脱交换,可以使用额外的数组。代码可在以下位置找到:

然后我像往常一样实现了快速排序():

因此,它基本上运行给定的
sort
函数,并打印排序数组所需的时间。所以我至少运行了10次这段代码,每次二进制插入排序几乎快了9倍(9s>1s)。但我认为快速排序是最快的。。。如果我比较这两种排序算法,我会说二进制插入排序更好,尽管它需要O(n)额外的空间(最糟糕的时间复杂度是O(n*log(n)),这比快速排序更好。
这是个错误吗?快速排序实际上比二进制插入排序更糟糕吗?我试图在互联网上找到它,但找不到真正与我的代码相似的东西。也许它甚至不是二进制插入排序,而是其他东西…(另一个名称)?

让我们看看您编写插入排序的尝试:

def insertion_sort_optimized(arr):
    array = [arr[0]]
    for i in range(1, len(arr)):
        index = bisect_left(array, i)
        array.insert(index, i)
    return array

您没有插入数组值,而是插入索引。以递增的顺序。这是错误的,正确的版本需要O(n^2)而不是O(n logn)(由于每个
插入的线性时间)。

这是我的二进制插入排序 时间复杂度为(N^2)/4+Nlog2(N/(2e))

def二进制索引(arr:Union[Iterable,List,Tuple,np.ndarray],value,reverse:bool=False):
如果值arr[-1]:
返回长度(arr)
开始,结束=0,长度(arr)
尽管如此:
如果结束-开始值:
回程起动
其他:
返回开始+1
其他:
如果arr[start]<值:
回程起动
其他:
返回开始+1
mid=(开始+结束)//2
如果反向为假:
如果值arr[mid]:
结束=中间
其他:
开始=中间
def BinaryInsertionSortOptimized(数组:联合[Iterable,List,Tuple,np.ndarray],反向:bool=False):
如果反向为假:
对于范围(1,len(数组))中的索引:
如果数组[索引-1]<数组[索引]:
持续
i=二进制索引(arr=array[0:index],value=array[index],reverse=reverse)
关键点=数组[索引]
数组[i+1:索引+1]=数组[i:索引]
数组[i]=关键点
其他:
对于范围(1,len(数组))中的索引:
如果数组[index-1]>数组[index]:
持续
i=二进制索引(arr=array[0:index],value=array[index],reverse=reverse)
关键点=数组[索引]
数组[i+1:索引+1]=数组[i:索引]
数组[i]=关键点
返回数组

您的快速排序没有得到有效实施,您已经将其变成了二次排序:
快速排序(小部分)+[pivot]+快速排序(大部分)
此外,在快速排序中,选择pivot是至关重要的,您使用的是最幼稚的策略。最后请注意,快速排序并不是应用最广泛的。例如,Python使用高度调优的自适应mergesort,Timsort。那么Java现在是否默认(采用Timsort)。@HeapOverflow你是什么意思?我不明白你的意思。。。我如何改进它?您的快速排序看起来像是在重新生成内容,而它被设想为就地排序。也许制作所有这些副本都要花费时间。但是快速排序不应该仍然是最快的吗?与Timsort和AdaptiveMergeSort相比?但是你的评论让我怀疑你对BigOoh不太了解。。。非常感谢。我看错地方了
def quicksort(arr):
    if len(arr) <= 1:
        return arr
    smaller_part = []
    larger_part = []
    pivot = arr[len(arr) - 1]
    for i in range(len(arr) - 1):
        if arr[i] < pivot:
            smaller_part.append(arr[i])
        else:
            larger_part.append(arr[i])
    return quicksort(smaller_part) + [pivot] + quicksort(larger_part)
def test_sorting_algorithm(sort=None, version="normal", returns=False, n=1000000):
    if version.lower() == "normal":
        print("Normal version:")
    else:
        print("Optimized version:")
    arr = [int(random() * n) for _ in range(n)]
    print(arr)

    start = time.time()
    if returns:
        arr = sort(arr)
    else:
        sort(arr)
    end = time.time()

    print(arr)
    print(f"Time elapsed: {end - start}\n")
def insertion_sort_optimized(arr):
    array = [arr[0]]
    for i in range(1, len(arr)):
        index = bisect_left(array, i)
        array.insert(index, i)
    return array
def BinaryIndexing(arr: Union[Iterable, List, Tuple, np.ndarray], value, reverse: bool = False):
    if value < arr[0]:
        return 0
    elif value > arr[-1]:
        return len(arr)

    start, end = 0, len(arr)
    while True:
        if end - start <= 1:
            if reverse is False:
                if arr[start] > value:
                    return start
                else:
                    return start + 1
            else:
                if arr[start] < value:
                    return start
                else:
                    return start + 1

        mid = (start + end) // 2

        if reverse is False:
            if value < arr[mid]:
                end = mid
            else:
                start = mid
        else:
            if value > arr[mid]:
                end = mid
            else:
                start = mid


def BinaryInsertionSortOptimized(array: Union[Iterable, List, Tuple, np.ndarray], reverse: bool = False):
    if reverse is False:
        for index in range(1, len(array)):
            if array[index - 1] < array[index]:
                continue
            i = BinaryIndexing(arr=array[0:index], value=array[index], reverse=reverse)
            key_point = array[index]
            array[i + 1:index + 1] = array[i:index]
            array[i] = key_point

    else:
        for index in range(1, len(array)):
            if array[index - 1] > array[index]:
                continue
            i = BinaryIndexing(arr=array[0:index], value=array[index], reverse=reverse)
            key_point = array[index]
            array[i + 1:index + 1] = array[i:index]
            array[i] = key_point
    return array