排序算法总结(python 3)

本文详细介绍了多种排序算法,包括冒泡排序、快速排序、插入排序、希尔排序、选择排序、归并排序、堆排序等,提供了Python实现代码,并通过实验验证了各种算法的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考:

http://wuchong.me/blog/2014/02/09/algorithm-sort-summary/
http://python.jobbole.com/82270/
https://blog.youkuaiyun.com/lm_is_dc/article/details/80048449

import random
import time
class Sort:
    def bubbleSort(self, array):
        for i in range(len(array)):
            for j in range(len(array) - i - 1):
                if array[j] > array[j + 1]:
                    array[j], array[j + 1] = array[j + 1], array[j]
    def exchangeSort(self, array):
        for i in range(len(array)):
            for j in range(i + 1, len(array)):
                if array[i] > array[j]:
                    array[i], array[j] = array[j], array[i]
    def insertSort(self, array):
        for i in range(1,len(array)):
            if array[i - 1] > array[i]:
                tmp = array[i]
                j = i - 1
                while array[j] > tmp and j >= 0:
                    array[j + 1] = array[j]
                    j -= 1
                array[j + 1] = tmp
                
    def insertSort_new(self, array):
        for i in range(len(array)):
            for j in range(i):
                if array[j] > array[i]:
                    array.insert(j, array.pop(i))
                    break
    def shellSort(self, array):
        n = len(array)
        gap = n // 2
        while gap != 0:
            for i in range(gap):
                for j in range(i, n - gap, gap):
                    if array[j + gap] < array[j]:
                        tmp = array[j + gap]
                        k = j
                        while array[k] > tmp and k >= i:
                            array[k + gap] = array[k]
                            k -= gap
                        array[k + gap] = tmp
            gap = gap // 2
    def selectSort(self, array):
        for i in range(len(array)):
            min = i
            for j in range(i,len(array)):
                if array[j] < array[min]:
                    min = j
            array[i], array[min] = array[min], array[i]
    def partition(self, array, left, right):
        sign = array[left]
        while left < right:
            while left < right and array[right] >= sign:
                right -= 1
            array[left] = array[right]
            while left < right and array[left] <= sign:
                left += 1
            array[right] = array[left]
        array[left] = sign
        return left

    def quickSort(self, array, left, right):
        if left < right:
            p = self.partition(array, left, right)

            self.quickSort(array, left, p)
            self.quickSort(array, p + 1, right)

    def quickSortWithoutRecursion(self, array):
        # 使用栈实现快速排序
        stack = []
        stack.append(0)
        stack.append(len(array) - 1)
        while stack:
            high = right = stack.pop()
            low = left = stack.pop()
            if low == high:
                continue
            left = self.partition(array, left, right)
            if left - 1 > low:
                stack.append(low)
                stack.append(left - 1)
            if left + 1 < high:
                stack.append(left + 1)
                stack.append(high)
    def mergSort(self, array):
        def merge(arr_l, arr_r):
            result = []
            while len(arr_l) and len(arr_r):
                if arr_l[0] < arr_r[0]:
                    result.append(arr_l.pop(0))
                else:
                    result.append(arr_r.pop(0))
            else:
                if len(arr_l):
                    result.extend(arr_l)
                else:
                    result.extend(arr_r)
            return result

        def merge_sort(array):
            length = len(array)
            if length == 1:
                return array
            n = length // 2
            arr_l = merge_sort(array[:n])
            arr_r = merge_sort(array[n:])
            return merge(arr_l, arr_r)

        return merge_sort(array)

堆排序时间复杂度:
调堆的时间复杂度为logN毋庸置疑,那么为什么建堆的时间复杂度不是logN呢,
很简单啊,如果从底部最后的父节点开始建堆,那么我们可以大概算一下:
假如有N个节点,那么高度为H=logN,最后一层每个父节点最多只需要下调1次,倒数第二层最多只需要下调2次,顶点最多需要下调H次,而最后一层父节点共有2(H-1)个,倒数第二层公有2(H-2),顶点只有1(2^0)个,所以总共的时间复杂度为s = 1 * 2^(H-1) + 2 * 2^(H-2) + … + (H-1) * 2^1 + H * 2^0
将H代入后s= 2N - 2 - log2(N),近似的时间复杂度就是O(N)。

更改堆元素后重建堆时间:O(nlogn)
推算过程:
循环 n -1 次,每次都是从根节点往下循环查找,所以每一次时间是 logn,总时间:logn(n-1) = nlogn - logn ;
综上所述:堆排序的时间复杂度为:O(nlogn)

    def heapSort(self, array):
        def heap_sort(ary):
            # 节点数
            n = len(ary)
            # 最后一个有子节点的节点(最后一个非叶节点)
            first = n // 2 - 1
            for start in range(first, -1, -1):
                # 对每一个非叶子节点倒序进行堆调整
                heap_adjust(ary, start, n - 1)
            for end in range(n - 1, 0, -1):
                # 交换最后一个叶节点和根节点
                ary[0], ary[end] = ary[end], ary[0]
                # 对新的堆进行调整
                heap_adjust(ary, 0, end - 1)

        def heap_adjust(ary, start, end):
            root = start
            while True:
                # 因为数组计数是从0开始,所以下式代表其左孩子
                child = 2 * root + 1
                # 左孩子超出数组范围:跳出
                if child > end: break
                # 挑选左右孩子中更大者
                if child + 1 <= end and ary[child] < ary[child + 1] :
                    child += 1
                # 交换双亲和子节点
                if ary[root] < ary[child]:
                    ary[root], ary[child] = ary[child], ary[root]
                    root = child
                else:
                    break
        heap_sort(array)

验证程序如下:


if __name__ == '__main__':
    srt = Sort()
    list = [random.randint(1, 999) for i in range(10000)]

    start = time.clock()
    list_true = sorted(list)
    end = time.clock()
    print("函数sorted排序   ", end - start, '\n')

    list1 = list.copy()
    start = time.clock()
    srt.quickSort(list1, 0, len(list1) - 1)
    end = time.clock()
    print("快速排序         ", end - start)
    print("排序结果         ", list1 == list_true, '\n')

    list2 = list.copy()
    start = time.clock()
    srt.quickSortWithoutRecursion(list2)
    end = time.clock()
    print("非递归快速排序   ", end - start)
    print("排序结果         ", list2 == list_true, '\n')

    list3 = list.copy()
    start = time.clock()
    srt.bubbleSort(list3)
    end = time.clock()
    print("冒泡排序         ", end - start)
    print("排序结果         ", list3 == list_true, '\n')

    list4 = list.copy()
    start = time.clock()
    srt.exchangeSort(list4)
    end = time.clock()
    print("交换排序         ", end - start)
    print("排序结果         ", list4 == list_true, '\n')

    list5 = list.copy()
    start = time.clock()
    srt.insertSort(list5)
    end = time.clock()
    print("插入排序         ", end - start)
    print("排序结果         ", list5 == list_true, '\n')

    list6 = list.copy()
    start = time.clock()
    srt.insertSort_new(list6)
    end = time.clock()
    print("新插入排序       ", end - start)
    print("排序结果         ", list6 == list_true, '\n')

    list7 = list.copy()
    start = time.clock()
    srt.shellSort(list7)
    end = time.clock()
    print("希尔排序         ", end - start)
    print("排序结果         ", list7 == list_true, '\n')

    list8 = list.copy()
    start = time.clock()
    srt.selectSort(list8)
    end = time.clock()
    print("选择排序         ", end - start)
    print("排序结果         ", list8 == list_true, '\n')

    list9 = list.copy()
    start = time.clock()
    list9 = srt.mergSort(list9)
    end = time.clock()
    print("归并排序         ", end - start)
    print("排序结果         ", list9 == list_true, '\n')

    list10 = list.copy()
    start = time.clock()
    srt.heapSort(list10)
    end = time.clock()
    print("堆排序           ", end - start)
    print("排序结果         ", list10 == list_true, '\n')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值