【LeetCode练习|算法通关手册:Python版】02. 数组篇_数组排序

2021.11.18-2021.11.22
Datawhale 11月学习内容;学习地址:https://algo.itcharge.cn/
本篇内容:精炼笔记+难点自己注解+习题多种解法

1. 排序

1.1 冒泡排序

在这里插入图片描述
思想

  • 就是两层循环
  • 每层循环将一个最大的排到最后
  • 不断缩小排序范围 直到所有都排完。

特点

  • 稳定排序法
  • 平均时间复杂度 O ( n 2 ) O(n^2) O(n2)
def bubbleSort(arr):
	for i in range(len(arr)):
		for j in range(len(arr)-i+1)):
			if arr[j] > arr[j+1]:
				arr[j], arr[j + 1] = arr[j + 1], arr[j]

1.2 选择排序

在这里插入图片描述
思想

  • 用一个变量记录最小的位置
  • 开始假设0号位是最小,那么遍历一遍,找到最小位置与0号交换位置
  • 第二轮从1号位开始找最小,直到所有都找一遍

特点

  • 其选择排序的最好、最坏、平均情况下复杂度都是 O ( n 2 ) O(n^2) O(n2)
  • 选择排序不是稳定性排序。举个例子:数组【6】、7、6、2、8 排序后 2、6、【6】、7、8
def selectSort(arr):
	for i in range(len(arr)-1):
		min_i = i
		for j in range(i+1, len(arr)):
			if arr[j] < arr[min_i]:
                min_i = j

		#如果找到最小数,将 i 位置上元素与最小数位置上元素进行交换
        if i != min_i:
            arr[i], arr[min_i] = arr[min_i], arr[i]

	return arr

注意:

  • 2个数时,只需要比较1次就可确定本轮最小值,3个数比较2次。 i比较的次数(第几轮)所以末端在len(arr)-1;
    -j则是比较数的位置,所以末端在len(arr)

1.3 插入排序

在这里插入图片描述

思想

  • 前面是已经排好的从小到大的顺序
  • 我们从后面取一根新的,逐一向前比较,插入新的位置,是前面依旧有序

特点

  • 稳定排序法
  • 最差情况是都是逆序,最好情况都是顺序,平均时间复杂度 O ( n 2 ) O(n^2) O(n2)
def insertionSort(arr):
    for i in range(1, len(arr)):
        temp = arr[i]
        j = i
        while j > 0 and arr[j - 1] > temp:
            arr[j] = arr[j - 1]
            j -= 1
        arr[j] = temp
        
    return arr

另一种写法:

def insertSort(arr):


    size = len(arr)

    # 一共要循环n次,i来索引新的
    for i in range(size):
        insert_i = i
        # 拿到一个元素 和所有后面的比较 找出最小的
        for j in range(i,0,-1):
            if arr[j] < arr[j-1]:
                arr[j-1], arr[j] = arr[j], arr[j-1]
    return arr
  • range(i,0,-1) 这个还是左闭右开,所以没有0,倒序,也就是从i开始 一直到1

1.4 希尔排序

在这里插入图片描述
思想

  • i是从一个gap以外开始的,0-i之间使我们要排的范围for i in range(gap,size)

在这里插入图片描述

  • 我们做的就是每隔一个gap保证是有序的。方法类似于冒泡,用jj-n*gap比较大小,让新进入的i落入到应该有的位置while j>=gap and arr[j - gap] > temp:

在这里插入图片描述

特点

  • 希尔排序方法的排序总躺数 l o g 2 n log_2n log2n 。中间层 do-while 循环为n 数量级。当子序列分得越多时,子序列内的元素就越少,最内层的 for 循环的次数也就越少;反之,当所分的子序列个数减少时,子序列内的元素也随之增多,但整个序列也逐步接近有序,而循环次数却不会随之增加。因此,希尔排序算法的时间复杂度在 O ( n 2 ) O(n^2) O(n2) O ( n l o g 2 n ) O(nlog_2n) O(nlog2n) 之间。
  • 是一种不稳定排序算法
def shellSort(arr):
	size = len(arr)
    gap = size // 2
    
    while gap > 0:
        for i in range(gap, size):
            temp = arr[i]
            j = i
            while j >= gap and arr[j - gap] > temp:
                arr[j] = arr[j - gap]
                j -= gap
            arr[j] = temp
        gap = gap // 2
    return arr

另一种写法:直接新进来的 与相对于的数比较 交换就行了

def shellSort(arr):
    size = len(arr)
    gap = size // 2
    while gap > 0:

        for i in range(gap, size):
            # 这里面可以不用j,全部用i 我这里为了方便理解
            j=i
            while j >= gap and arr[j-gap] > arr[j]:
                # 用新进来较小的 和前面比他大的不断交换位置
                arr[j-gap], arr[j] = arr[j], arr[j-gap]
                j = j-gap
        gap = gap // 2
    return arr

1.5 归并排序

在这里插入图片描述
思想:

  • 先小范围排序,不断扩排序范围
  • (2), (2), (2), (2),排
  • (2, 2), (2, 2) 排
  • (2, 2,2, 2) 排

特点

  • 稳定排序算法
  • 归并排序算法的时间复杂度等于归并趟数与每一趟归并的时间复杂度成绩。子算法 merge(left_arr, right_arr) 的时间复杂度是 O ( n ) O(n) O(n),因此,归并排序算法总的时间复杂度为 O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)
def merge(left_arr, right_arr):
	arr = []
	whiel left-arr or right_arr:
		if left-arr[0] <= right_arr[0]:
			arr.append(left_arr.pop(0))
		else:
			arr.append(right_arr.pop(0))
		while left_arr:
			arr.append(left_arr.pop(0))
		while right_arr:
			arr.append(right_arr.pop(0))
		return arr

	def mergeSort(arr):
		size = len(arr)
		if size < 2:
			return arr
		mid =
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

羊老羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值