• 十大排序代码实现(python)


    写在前面:

    参考文章:十大经典排序算法 本文的逻辑顺序基于从第一篇参考博文上借鉴过来的图,并且都是按照升序排序写的程序,程序语言采用python


    思路:

    冒泡排序的基本思想就是让小的数逐渐‘浮上来’。也就是说:

    • 第一次冒泡:将最小的数调换到最前面;

    • 第二次冒泡:将第二小的数调换到最小的数的后面,也就是数组中的第二位;

    • 第三次冒泡,将第三小的数调换到数组中的第三位;

      ... ...

    代码如下:

    # 冒泡排序
    def bubble_sort(nums):
        # 每次冒泡,将最大的元素冒到最后面
        # 第一次是前n个元素,最大的元素冒到最后
        # 第二次是前n-1个元素,最大的元素冒到倒数第二个位置
        # ... ...
        n = len(nums)
        for i in range(n-1):
            for j in range(0,n-i-1):
                if nums[j]>nums[j+1]:
                    nums[j], nums[j+1] = nums[j+1],nums[j]
                    
        return nums
    

    时间复杂度: O(n^2),实际上是n-1 + n-2 + n-3 + ...,所以是平方的量级。

    空间复杂度: O(l),没有借助额外空间。


    快速排序

    参考:快速排序的四种写法(python实现)

    思路

    快速排序的基本思路就是在一遍快排中,以基准值为基础,将比基准值小的数放到基准值的左边,比基准值大的数放在基准值的右边。然后在递归的快排基准值的左边和右边。至于基准值的取法,理论上来讲是无所谓的。

    先来一个比较简单直接的吧。它的思路就是遍历一遍数组,用两个空的数组来存储比基准值大和比基准值小的数,代码如下:

    def quick_sort1(nums):
        n = len(nums)
        if n ==1 or len(nums)==0:
            return nums  
        left = []
        right = []
        for i in range(1,n):
            if nums[i] <= nums[0]:
                left.append(nums[i])
            else:
                right.append(nums[i])         
        return quick_sort1(left)+[nums[0]]+quick_sort1(right)
    

    上面的使用了额外的空间,空间复杂度比较高,下面是基于双指针的想法的代码,比较常见:

    def quick_sort2(nums,left,right):
        l,r = left,right-1
        while  l < r:
            if nums[r] < nums[l]:
                nums[r], nums[l] = nums[l], nums[r]
                l += 1
                while l < r:
                    if nums[l] > nums[r]:
                        nums[r],nums[l] = nums[l], nums[r]
                        r -= 1
                        break
                    else:
                        l += 1
            else:
                r -= 1
        if l-left > 1:                
            quick_sort2(nums, left, l)
        if right - r > 1:
            quick_sort2(nums, l+1, right)
        return nums
    

    在上面博客中看到的第三种方法,甚是巧妙,代码如下:

    def quick_sort3(nums, l, r):
        if l < r:
            q = partition(nums, l, r)
            quick_sort(nums, l, q - 1)
            quick_sort(nums, q + 1, r)
        return nums        
    def partition(nums, l, r):
        x = nums[r]
        i = l - 1
        for j in range(l, r):
            if nums[j] <= x:
                i += 1
                nums[i], nums[j] = nums[j], nums[i]
        nums[i + 1], nums[r] = nums[r], nums[i+1]
        return i + 1
    

    简单插入排序

    插入排序,意思是将某一个数字插入到已经排好序的数组当中。

    代码如下:

    def insert_sort(nums):
        n = len(nums)
        for i in range(1,n):
            index = i
            for j in range(i-1,-1,-1):
                if nums[j] > nums[index]:
                    nums[index],nums[j] = nums[j],nums[index]
                    index -= 1
                else:
                    break
        return nums
    

    希尔排序


    简单选择排序

    简单选择排序,就是每一次选择一个当前最小的元素放在已经排好序的数组的后面。

    def selection_sort(nums):
        n = len(nums)
        for i in range(n):
            index = i
            for j in range(i+1,n):
                if nums[j]<nums[index]:
                    index = j
            nums[i],nums[index] = nums[index],nums[i]
    
        return nums
    

    堆排序

    def head_sort(elems):
        def siftdown(elems,e,begin,end):
            i, j = begin, begin*2+1
            while j < end:
                if j+1 < end and elems[j+1] < elems[j]:
                    j += 1
                if e < elems[j]:
                    break
                elems[i] = elems[j]
                i, j = j, 2*j+1
            elems[i] = e
    
        end = len(elems)
        for i in range(end//2, -1, -1):
            siftdown(elems, elems[i], i, end)
        for i in range((end-1), 0, -1):
            e = elems[i]
            elems[i] = elems[0]
            siftdown(elems, e, 0, i)
    
        nums.reverse()
        return nums
    

    二路归并排序


    多路归并排序


    计数排序


    桶排序


    基数排序


  • 相关阅读:
    难得之货,令人行妨
    Oracle死锁
    log4j杂记
    Oracle9或11使用了Oracle10的驱动引起的时间丢失
    程序员要重视过劳
    oracle提供的有用函数(待续)
    Mysql扩展之replication概述
    @autowired与@qualifer的使用区别备忘
    Oracle中的in参数的个数限制
    java版正则式提取替换示例
  • 原文地址:https://www.cnblogs.com/anzhengyu/p/11282769.html
Copyright © 2020-2023  润新知