每天一道面试题:day01

308 阅读2分钟

最近在准备面试,特写此系列整理python面试笔试中常遇到的问题,并记录自己的解答,欢迎大家讨论并指正。

question:实现一种排序算法,并说明其算法复杂度

answer:
第一时间想到的是归并排序和快速排序,两者都是采用分治的思想,各有所长。
归并排序是稳定的(排序完成后相同元素的相对位置不发生变化),时间复杂都是O(nlogn),空间复杂度是O(n)。
快速排序是不稳定的,平均时间复杂度也是O(nlogn),空间复杂度是O(logn)。虽然最坏时间复杂度是O(n^2),但概率极小,一般情况下都默认是O(nlogn)的时间复杂度,但相比归并排序,它的时间复杂度常量要更小,所以在数据量不是非常大的情况下快排会比归并运行速度更快。下面是代码:

'''
归并排序
'''
def mergesort(array):
    if len(array)<=1:   #终止条件(数组为空或只有一个元素)
        return array
    mid=(len(array)-1)//2   #中间位置的索引
    left=mergesort(array[:mid+1])
    right=mergesort(array[mid+1:])  #递归地分成左右两半部分
    def merge(left,right):
        #把左右两部分已经排序好的数组按顺序归并到一个新的数组里
        res=[]
        i=j=0   #两个指针指向左右两部分待归并数组的首元素
        while i<len(left) and j<len(right):
            if left[i]<=right[j]:
                res.append(left[i])
                i+=1
            else:
                res.append(right[j])
                j+=1
        #此时只可能left数组剩余部分元素或者right数组剩余部分元素
        #把剩余的元素直接放进res数组中
        res.extend(left[i:])
        res.extend(right[j:])
        return res
    array=merge(left,right)
    return array

if __name__ == '__main__':
    list01=[5,10,11,19,5,4,0]
    print(mergesort(list01))
'''
快速排序
'''
def quicksort(array):
    l = 0
    r = len(array) - 1
    def qsort(l,r):
        if l>=r:    #终止条件(数组为空或只有一个元素)
            return
        key=array[l]    #随机选择一个元素,这里不妨选择第一个元素
        i=l
        j=r #定义双指针遍历数组
        while i<j:
            while array[j]>=key and j>i:
                j-=1
            array[i]=array[j]
            while array[i]<key and i<j:
                i+=1
            array[j]=array[i]
        array[i]=key #遍历结束时i=j,赋值key
        qsort(l,i)
        qsort(i+1,r)
    qsort(l,r)
    return array

if __name__ == '__main__':
    print(quicksort([5,11,2,66,44,22,1,11,0]))