三大排序算法的Python写法

前言

最近找工作,刷了一下牛客网上的剑指offer算法题,接触到了排序算法。为了熟练掌握常用的三种排序算法:快速排序(quickSort),归并排序(mergeSort)和堆排序(heapSort),我查阅资料整理了一下他们的Python实现算法。本文默认排序是从小到大排序。有问题的话,欢迎交流与讨论。

原理

首先简单介绍下这三种排序算法的原理,如下:

  • 快速排序(quickSort):采用分而治之的思想,选择一个基准数(pivot),将小于基准数的值全放在其左侧,大于基准数的值放在其右侧。然后分别对其左右侧的子数组进行排序,直到子数组只包含一个或零个数为止。
  • 补充:非递归版的快速排序其实思路很简单,就是将长度大于1的子数组(需要进一步排序)保存在一个大数组res中,循环排序,直到每个子数组长度均为1为止。
  • 归并排序(mergeSort):也是采用分而治之的思想,先对数组进行分解,迭代地使用二分法划分,直到子数组只包含一个或零个数为止,再将有序的子数组迭代的进行合并,数值小的在前,数值大的在后。
  • 堆排序(heapSort):基于堆这种数据结构的排序方法,首先将数组构建成一个最大堆,然后逐步将堆顶元素与堆的最后一个元素交换,重新调整最大堆,直至堆中仅剩一个元素为止。

实现

# -*- coding: utf-8 -*-

################快速排序################
#递归版
def quickSort(array):
    if len(array)<2:
        return array
    else:
        pivot = array[0]
        less = [i for i in array[1:] if i<=pivot]
        greater = [i for i in array[1:] if i>pivot]
        return quickSort(less)+[pivot]+quickSort(greater)

#非递归版
#我的思路:很简单,就是将长度大于1的子数组(需要进一步排序)保存在一个大数组res中,循环排序,直到每个子数组长度均为1为止
def quickSort_(array):
    if len(array)<2:
        return array
    else:
        res = [array]
        while len(res)!=len(array):
            temp = []
            for r in res:
                if len(r)==1:
                    temp.append(r)
                else:                    
                    pivot = r[0]
                    less = [i for i in r[1:] if i<=pivot]
                    greater = [i for i in r[1:] if i>pivot]
                    if len(less)>0: temp.append(less)
                    temp.append([pivot])
                    if len(greater)>0: temp.append(greater)
            res = temp 
        out = []
        for r in res:
            out += r
        return out

################归并排序################
def mergeSort(array):
    if len(array)<2:
        return array
    else:
        mid = int(len(array)/2)
        return merge(mergeSort(array[:mid]), mergeSort(array[mid:]))
    
def merge(left, right):
    res = []
    while left and right:
        if left[0]<=right[0]:
            res.append(left.pop(0))
        else:
            res.append(right.pop(0))
    res += left
    res += right
    return res

################堆排序################      
def heapSort(array):
    if len(array)<2:
        return array
    #make a max heap
    n = len(array)
    for i in range(n)[::-1]:
        array = heapAdjust(array, i, n)
    #sort
    for i in range(1,n)[::-1]:
        array[0], array[i] = array[i], array[0]
        array = heapAdjust(array, 0, i)
    return array

def heapAdjust(array, start, end):
    while start<=end:
        l = 2*start+1
        r = 2*start+2
        maxid = start
        if larray[maxid]:
            maxid = l
        if rarray[maxid]:
            maxid = r
        if maxid!=start:
            array[maxid], array[start] = array[start], array[maxid]
        start += 1
    return array

###############测试#####################
#test                    
ab = [3,2,1,4,7,5,6]
print(heapSort(ab))    
#[out]: [1, 2, 3, 4, 5, 6, 7]

补充:另一种非递归实现的快速排序算法,利用栈的思想,将需要继续排序的首尾下标存入栈中,不断弹栈进行分区操作,代码如下:

def quick_sort(arr):
    '''''
    模拟栈操作实现非递归的快速排序
    '''
    if len(arr) < 2:
        return arr
    stack = []
    stack.append(len(arr)-1)
    stack.append(0)
    while stack:
        l = stack.pop()
        r = stack.pop()
        index, arr = partition(arr, l, r)
        if l < index - 1:
            stack.append(index - 1)
            stack.append(l)
        if r > index + 1:
            stack.append(r)
            stack.append(index + 1)
    return arr


def partition(arr, start, end):
    # 分区操作,返回基准线下标
    pivot = arr[start]
    while start < end:
        while start < end and arr[end] >= pivot:
            end -= 1
        arr[start] = arr[end]
        while start < end and arr[start] <= pivot:
            start += 1
        arr[end] = arr[start]
    # 此时start = end
    arr[start] = pivot
    return start, arr

参考:

https://blog.csdn.net/qq_34178562/article/details/79903871

你可能感兴趣的:(python,数据结构,python,数据结构,排序算法)