zoukankan      html  css  js  c++  java
  • Python 基础排序算法

    冒泡排序(bubble sort)

    思路

    以升序为例:
    从第一个数开始向后两两对比,将大的数一直向后移动,直至最大的数移到最后,再找第二大的数
    最好情况:O(n)
    一般情况:O(n^2)
    最坏情况:O(n^2)

    代码

    import random
    
    
    def bubble_sort(l):
        for i in range(len(l) - 1):
            exchange = False
            for j in range(len(l) - 1 - i):
                if l[j] > l[j + 1]:
                    l[j], l[j + 1] = l[j + 1], l[j]
                    exchange = True
            if not exchange:	# 如果一次循环中都没有交换,则说明已经排序完成,可以提前结束
                break
    
    
    if __name__ == '__main__':
        data = list(range(1000))
        random.shuffle(data)
        bubble_sort(data)
        print(data)
    
    

    选择排序(selection sort)

    思路

    以升序为例:
    从第一个位置开始向后寻找,找到最小的数,放在这个位置,之后向后移一个位置

    时间复杂度

    最好情况:O(n^2)
    一般情况:O(n^2)
    最坏情况:O(n^2)

    代码

    import random
    
    
    def selection_sort(l):
        for i in range(len(l) - 1):
            min_num = i
            for j in range(i + 1, len(l)):
                if l[j] < l[min_num]:
                    min_num = j
            if min_num != i:
                l[i], l[min_num] = l[min_num], l[i]
    
    
    if __name__ == '__main__':
        data = list(range(1000))
        random.shuffle(data)
        selection_sort(data)
        print(data)
    
    

    插入排序(insertion sort)

    思路

    以升序为例:
    将第一个数分为有序队列,后面为无序队列。从二个数开始,依次插入前面有序队列

    时间复杂度

    最好情况:O(n)
    一般情况:O(n^2)
    最坏情况:O(n^2)

    代码

    import random
    
    
    def insertion_sort(l):
        for i in range(1, len(l)):
            tem = l[i]
            j = i - 1
            while j >= 0 and tem < l[j]:
                l[j + 1] = l[j]
                j -= 1
            l[j + 1] = tem
    
    
    if __name__ == '__main__':
        data = list(range(1000))
        random.shuffle(data)
        insertion_sort(data)
        print(data)
    
    

    快速排序(quicksort)

    Python 的 sort 时间复杂度为 O(nlogn),但是因为是 C 写的,所以会快

    思路

    以升序为例:
    从第一个数开始,将其他数分成两部分,小于这个数的放在左边,大于这个数的放在右边,分出的左右两边分别继续执行。

    时间复杂度

    最好情况:O(nlogn)
    一般情况:O(nlogn)
    最坏情况:O(n^2)

    代码

    import random
    
    
    def quick_sort(l, left, right):
        if left < right:
            mid = partition(l, left, right)
            quick_sort(l, left, mid - 1)
            quick_sort(l, mid + 1, right)
    
    
    def partition(l, left, right):
        tem = l[left]
        while left < right:
            # 一次循环左右各移动一位
            while left < right and l[right] > tem:
                # 当前位不需要换位置,指针向内移动一位,直至遇到需要换位置的位
                right -= 1
            l[left] = l[right]  # 将右边需要换位置的换到左边(取出的数之前的位置)
            while left < right and l[left] < tem:
                left += 1
            l[right] = l[left]
        l[left] = tem
        return left
    
    
    if __name__ == '__main__':
        data = list(range(1000))
        random.shuffle(data)
        quick_sort(data, 0, len(data) - 1)
        print(data)
    
    

    堆排序(heapsort)

    思路

    以升序为例:
    借助最大堆(大根堆)的特性,依次取出堆中最大的数(根结点的数),再对堆进行调整

    时间复杂度

    最好情况:O(nlogn)
    一般情况:O(nlogn)
    最坏情况:O(nlogn)

    代码

    import random
    
    
    def sift(l, low, high):
        i = low     # 指向父节点
        j = 2 * i + 1   # 指向左节点
        tem = l[i]   # 获取父节点的值
        while j <= high:    # 如果子节点在堆中(有子节点)
            if j < high and l[j] < l[j + 1]:  # 有右节点且比左节点大
                j += 1      # 指向右节点
            if tem < l[j]:   # 如果根结点小于子节点中较大的那个
                l[i] = l[j]   # 将较大的值放入父节点
                i = j   # 指向下一层树
                j = 2 * i + 1
            else:
                break
        l[i] = tem   # 将循环开始时的父节点数据写入
    
    
    def heap_sort(l):
        n = len(l)
        for i in range(n // 2 - 1, -1, -1):
            sift(l, i, n - 1)
            # 堆建好了
        for i in range(n - 1, -1, -1):      # i 指向堆堆最后
            l[0], l[i] = l[i], l[0]     # 将当前最大数移到最后,最后的数移到根结点
            sift(l, 0, i - 1)
    
    
    if __name__ == '__main__':
        data = list(range(1000))
        random.shuffle(data)
        heap_sort(data)
        print(data)
    
    

    归并排序(merge sort)

    思路

    以升序为例:
    由于将两个有序列表合并比较简单,所以将列表无限分割成仅有一个元素的有序列表,之后再合并

    时间复杂度

    最好情况:O(nlogn)
    一般情况:O(nlogn)
    最坏情况:O(nlogn)

    代码

    import random
    
    
    def merge_sort(l, low, high):
        if low < high:
            mid = (low + high) // 2
            merge_sort(l, low, mid)     # 前半部分迭代
            merge_sort(l, mid + 1, high)    # 后半部分迭代
            merge(l, low, mid, high)    # 调整
    
    
    def merge(l, low, mid, high):
        """
        用于将两个有序列表进行合并
        """
        i = low         # 指向左边有序列表第一个元素
        j = mid + 1     # 指向右边有序列表第一个元素
        tem_l = []      # 临时列表,用于存放合并后列表
        while i <= mid and j <= high:
            # 当左右列表中都有元素时
            if l[i] <= l[j]:
                tem_l.append(l[i])
                i += 1
            else:
                tem_l.append(l[j])
                j += 1
        while i <= mid:
            # 当左边列表中有元素时,直接将剩下的元素全部插入临时列表
            tem_l.append(l[i])
            i += 1
        while j <= high:
            # 当右边列表中有元素时,直接将剩下的元素全部插入临时列表
            tem_l.append(l[j])
            j += 1
        # 用排序完成的元素替代未排序的元素
        l[low:high + 1] = tem_l
    
    
    if __name__ == '__main__':
        data = list(range(1000))
        random.shuffle(data)
        merge_sort(data, 0, len(data) - 1)
        print(data)
    
    

    希尔排序(Shell's sort)

    思路

    以升序为例:
    将元素分为n组,每一组进行插入排序,再将每组元素增加直至所有元素都在一组中

    时间复杂度

    O((1 + τ)n)
    一般情况:O(1.3n)

    代码

    import random
    
    
    def shell_sort(l):
        gap = len(l) // 2
        while gap > 0:
            for i in range(gap, len(l)):
                tem = l[i]
                j = i - gap     # 指向同组前一个元素
                while j >= 0 and tem < l[j]:    # 存在前一个元素并且比当前元素大
                    l[j + gap] = l[j]           # 将前一个元素移到后面一位
                    j -= gap                    # 指向前一个元素
                l[j + gap] = tem
            gap //= 2
    
    
    if __name__ == '__main__':
        data = list(range(1000))
        random.shuffle(data)
        shell_sort(data)
        print(data)
    
    
  • 相关阅读:
    SPSS简单数据分析之分类汇总数据
    如何使用思维导图软件MindManager培养英语能力
    iMindMap画图技巧有哪些
    思维导图MindManager给我们的工作生活带来哪些便利
    bt下载器Folx智能标签系统可以用来做什么
    Beyond Compare文件夹同步详解
    RayFire Voronoi放射型破碎法相关属性详解
    怎么使用ABBYY FineReader 14填写表格
    详解MindMapper查看视图
    软件工程课程总结
  • 原文地址:https://www.cnblogs.com/dbf-/p/11209193.html
Copyright © 2011-2022 走看看