常用排序算法总结(python)

参考:https://wiki.jikexueyuan.com/project/easy-learn-algorithm/xiaohen-buy-book.html

https://note.youdao.com/ynoteshare1/index.html?id=3a18b006135addae625ccf0255303fc7&type=note

https://blog.csdn.net/qq_34228570/article/details/80024306

https://www.cnblogs.com/morewindows/archive/2011/08/22/2149612.html

【leetcode912】排序树组

常用的排序算法有:

  1. 桶排序
  2. 冒泡排序
  3. 快速排序
  4. 堆排序
  5. 插入排序
  6. 归并排序

1、桶排序:好多桶。时间复杂度为O(m+n),空间复杂度为O(max(nums)+1)

#打印出得分[5, 3, 2, 5, 8]
#10为总分数
#堆排序
def backet_sort(nums):#时间复杂度O(m+n)
    res = []
    size = len(nums)
    if size < 2:
        return nums
    backet = [0 for _ in range(10+1)]

    for n in nums:
        backet[n] += 1
    #从小到大
    # for i in range(10+1):
    #从大到小
    for i in range(10, -1, -1):
        l = backet[i]
        for j in range(l):
            res.append(i)
    return res
# print(backet_sort([5, 3, 2, 5, 8]))

2、冒泡排序:有点像排大合照站队形;时间复杂度O(n2),空间复杂度O(1)

思路:一轮滚动确定最后一个元素(最大的元素),二轮滚动确定倒数第二个元素,从后往前确定元素

参考:https://www.cnblogs.com/SteveWesley/p/10007987.html

#冒泡排序
#def bulling_sort(nums):
class Solution:
    def sortArray(self, nums):
        for i in range(len(nums) - 1):
            for j in range(len(nums) - i - 1):
                if nums[j + 1] < nums[j]:
                    nums[j + 1], nums[j] = nums[j], nums[j + 1]
        return nums

优化:某一趟遍历如果没有数据交换,则说明已经排好序了,因此不用再进行迭代了。用一个标记记录这个状态即可。

class Solution:
    def sortArray(self, nums):
        for i in range(len(nums) - 1):
            flag = True
            for j in range(len(nums) - i - 1):
                if nums[j + 1] < nums[j]:
                    nums[j + 1], nums[j] = nums[j], nums[j + 1]
                    flag = False
            if flag:
                break
        return nums

3、快排:找基准值,两个左右两个指针相遇;时间复杂度O(nlogn),空间复杂度为O(1).

#快排
def quick_sort(nums):
    size = len(nums)
    if size < 2:
        return nums
    pivot = nums[0]
    i = 0
    j = size - 1
    while i < j:
        if nums[j] > pivot:
            j -= 1
        else:
            if nums[i] > pivot:
                tmp = nums[i]
                nums[i] = nums[j]
                nums[j] = tmp
            else:
                i += 1
    tmp = nums[i]
    nums[i] = pivot
    nums[0] = tmp
    return quick_sort(nums[:i]) + [pivot] + quick_sort(nums[i+1:])
print(quick_sort([6, 1, 2, 7, 3, 4, 5, 10, 8]))

4、归并:先得到两个有序数组,然后合并。时间复杂度O(nlogn),空间复杂度O(n)

快排和归并排序都是用分而治之的思想去实现的。

#归并排序一句话总结:分而治之,先得到两个排序数组,然后合并为一个。
def mergesort(nums):
    def merge(left, right):
        res = []
        i, j = 0, 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
        res = res + left[i:] + right[j:]
        return res
    if len(nums) <= 1:
        return nums
    mid = len(nums) // 2
    left = mergesort(nums[:mid])
    right = mergesort(nums[mid:])
    return merge(left, right)

5、插入排序:时间复杂度:O(n2) 空间复杂度:O(1)【从前往后确定元素】

对于每个未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。第一个认为已排序

  1. 从第一个元素开始,该元素可以认为已经被排序
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
  3. 如果被扫描的元素(已排序)大于新元素,将该元素后移一位
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
  5. 将新元素插入到该位置后
  6. 重复步骤2~5
def insertsort(nums):
    if len(nums) <= 1:
        return nums
    for i in range(1, len(nums)):
        j = i - 1
        tmp = nums[i]
        while j >= 0 and tmp < nums[j]:
            nums[j+1] = nums[j]
            j -= 1
        nums[j+1] = tmp
    return nums

6、堆排序:先求出最小堆(先写出down(类似插入排序),然后取一半-1,依次4,3210),然后从后往前依次改变列表值,构成递减序列

对于数组堆:父节点为i,子节点为2i+1和2i+2

时间复杂度O(nlogn), 空间复杂度为O(1)

初始化堆的时间复杂度为O(n),堆排序的时间复杂度为O(nlogn)

def min_heapsort(nums):
    def down(nums, start, n):
        if len(nums) == 0:
            return
        i = start
        j = 2 * i + 1
        tmp = nums[i]
        while j < n:
            if j < n-1 and nums[j+1] < nums[j]:
                j += 1
            if nums[j] > tmp:
                break
            nums[i] = nums[j]
            i = j
            j = 2 * i + 1
        nums[i] = tmp
    n = len(nums)
    j = n // 2 - 1
    while j >= 0:
        down(nums, j, n)
        j -= 1
    nums = min_heap(nums, 0, len(nums))
    i = len(nums) - 1
    while i > 0:
        nums[0], nums[i] = nums[i], nums[0]
        down(nums, 0, i)
        i -= 1
    return nums
nums = [8,1,1,2,4,4,1,3,3,2]
print(min_heapsort(nums))

 

第二次复习排序算法,发现归并和插入排序,还存在一些问题。

复习如下:

'''排序算法'''
'''--------------------------快排-----------------------'''
nums = [6, 3, 4, 1, 5]
def quicksort1(nums):
    if len(nums) == 0:
        return []
    pivot = nums[0]
    left = 0
    right = len(nums) - 1
    while left < right:
        if nums[right] >= pivot:
            right -= 1
        else:
            if nums[left] <= pivot:
                left += 1
            else:
                nums[left], nums[right] = nums[right], nums[left]
    nums[0], nums[left] = nums[left], nums[0]
    return quicksort1(nums[:left]) + [pivot] + quicksort1(nums[left+1:])
# print(quicksort1(nums))
'''--------------------------冒泡-----------------------'''
def bubblingsort1(nums):
    if len(nums) == 0:
        return []
    for i in range(1, len(nums)):
        for j in range(len(nums) - i- 1):
            if nums[j + 1] > nums[j]:
                nums[j + 1], nums[j] = nums[j], nums[j + 1]
    return nums
# print(bubblingsort1(nums))
'''--------------------------插入-----------------------'''
def insertsort1(nums):
    if len(nums) <= 1:
        return nums
    for i in range(1, len(nums)):
        j = i - 1
        tmp = nums[i]
        while j >= 0 and tmp < nums[j]:
            nums[j+1] = nums[j]
            j -= 1
        nums[j+1] = tmp
    return nums
# print(insertsort1(nums))
'''--------------------------归并-----------------------'''
#归并排序一句话总结:分而治之,先得到两个排序数组,然后合并为一个。
def mergesort1(nums):
    if len(nums) <= 1:
        return nums
    mid = len(nums) // 2
    left_tree = mergesort1(nums[:mid])
    right_tree = mergesort1(nums[mid:])
    def merge(nums1, nums2):
        i = 0
        j = 0
        res = []
        while i < len(nums1) and j < len(nums2):
            if nums1[i] < nums2[j]:
                res.append(nums1[i])
                i += 1
            else:
                res.append(nums2[j])
                j += 1
        res += nums1[i:] + nums2[j:]
        return res
    return merge(left_tree, right_tree)
# print(mergesort1(nums))
'''--------------------------堆排-----------------------'''
def heapsort1(nums):
    def down(nums, start, end):
        tmp = nums[start]
        i = start
        j = 2 * i + 1
        while j <= end:
            if j + 1 <= end and nums[j+1] > nums[j]:
                j += 1
            if nums[j] <= tmp:
                break
            nums[i] = nums[j]
            i = j
            j = 2 * i + 1
        nums[i] = tmp
    def max_heap(nums):
        i = len(nums) // 2 - 1
        while i >= 0:
            down(nums, i, len(nums)-1)
            i -= 1
        return nums
    # return max_heap(nums)
    nums = max_heap(nums)
    i = len(nums) - 1
    while i >= 1:
        nums[0], nums[i] = nums[i], nums[0]
        down(nums, 0, i-1)
        i -= 1
    return nums
print(heapsort1(nums))

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值