冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序六大排序大总结

欢迎一起讨论学习(*^__^*) Python技术分享群:  556993881

注!以下的方法实现的都是从小到大排列

1、冒泡排序

释义:

1、假设:            假设第一个数是最大值,

2、依次比较:    将第一个数与后面的每个数进行比较,

3、 替换:           谁大就与"最大值"替换, 继续往后比较, 

4、得到最大值:直到比较到最后一个, 将真的最大值放最后

5、缩围重复执行:得到修改一次的序列后,重复1、2、3,比较到倒数第二位即可(倒数第一位已经在上一轮比较过了,是最大的值)此时得到的是较大的值,放在倒数第二位

6、........以此类推,大一点数据像泡泡一样一个接着一个慢慢浮出到后面的位置,得到由大到小的有序序列


# 方法一
def bubble_sort1(li):
    n = len(li)
    for j in range(n-1):  # 遍历n-1次,从0开始
        for i in range(n-1-j):  # 遍历(n-1)-1次,从下一个开始
            if li[i] > li[i+1]:  # 比较
                li[i], li[i+1] = li[i+1], li[i]  # 替换


# 方法二 只是因为内循环用到了外循环的 j ,然后界限做了调整
def bubble_sort2(li):
    n = len(li)
    for j in range(n-1, 0, -1):  # 遍历次数,下标倒着开始
        for i in range(j):
            if li[i] > li[i+1]:
                li[i], li[i+1] = li[i+1], li[i]

# 调用
l = [3, 0, 1, 8, 7, 2, 5, 4, 9, 6]
bubble_sort1(l)
bubble /ˈbʌb(ə)l/ 气泡


最坏时间复杂度:O(n^2)
最优时间复杂度:O(n) (就是一个有序的序列)
稳定


2、选择排序

释义:

1、标记:找个变量记录第一个值的下标

2、遍历比较:从它后面开始遍历到最后一个值,与这第一个值进行比较

3、更改下标:如果出现更小的,就将变量记录更小值的下标

4、替换:一次循环结束将第一个值和下标所在的值进行替换

5、从第二个值开始,继续执行1、2、3、4

6、.......以此类推,直到遍历比较到倒数第二个值

def select_sort(li):
    n = len(li)
    for j in range(n-1):  # 循环n-1次,从0开始
        temp = j
        for i in range(j+1, n):  # 从下一个开始
            if li[i] < li[temp]:  # 比较
                temp = i  # 更改标记
        li[j], li[temp] = li[temp], li[j]  # 替换

# 调用
l = [3, 0, 1, 8, 7, 2, 5, 4, 9, 6]
select_sort(l)

最坏时间复杂度:O(n^2)
最优时间复杂度:O(n^2)
不稳定(假设前后出现两次8,第一个出现的8反而被调整在最后)


3、插入排序

释义:

1、划分有序序列:将第一个元素作为有序的序列看待

2、依次比较:        把后面的一个元素与前面的有序序列中的所有元素依次从后往前进行比较

3、调换位置:  将该元素与比它大的交换,直到找到正确的位置

4、......以此类推,将序列中的所有元素,从左到右全部确定


# 方法一
def insert_sort(li):
    n = len(li)
    for j in range(n-1):
        for i in range(j+1, 0, -1):
            if li[i] < li[i-1]:
                li[i], li[i-1] = li[i-1], li[i]

# 方法二
def insert_sort(li):
    n = len(li)
    for j in range(1,  n): 
        for i in range(j, 0, -1): 
            if li[i] < li[i-1]:
                li[i], li[i-1] = li[i-1], li[i]

# 调用
l = [3, 0, 1, 8, 7, 2, 5, 4, 9, 6]
insert_sort(l)


最坏时间复杂度:O(n^2)
最优时间复杂度:O(n)
稳定


4、希尔排序

释义:

1、设定步长:将步长设定为序列长度的一半;

2、比较:   从步长后的元素开始往前(与和自己相差步长的元素)进行比较;

3、交换:   小的在前,大的在后,若再往前移动一个步长还有数值切大于自己那么继续往前比较,直到遇到比自己小或者不存在差  步长的元素;

4、调整步长:步长为上一次步长的一半(也可根据自己喜好划分步长,但最后一定要有一次步长为1的比较,相当于插入排序)

5、3处的交换不好理解,请运行代码,静下心来分析一下

def shell_sort(li):
    n = len(li)
    gap = n//2  # gap:步长,或者看作∆x
    while gap > 0:
        for i in range(gap, n):  # 步长~最后
            # i, i+1 ,i+2
            while i-gap >= 0:  # 将后面调整的数与前面步长差的数进行调整
                if li[i] < li[i - gap]:
                    li[i], li[i - gap] = li[i - gap], li[i]
                    i -= gap
                else:
                    break
        gap -= 1
# 调用
l = [3, 0, 1, 8, 7, 2, 5, 4, 9, 6]
shell_sort(l)


时间复杂度:O(n) < O < O(n^2), 因为每个人的步长设定不同,认为是对插入排序的优化
不稳定

5、快速排序

释义: 采用一分为二法,或者二分法

1、设定一个中间值:将第一个元素假定为中间值,

2、从列表最后一位开始从右往左的将其他元素与之比较,遇到小的与第一位交换,

3、然后更改方向,从第一位的后一位从左往右的将未比较的元素拿来与之(中间值)比较,遇到大的与 2 中右边交换的元素进行交换,

4、方向再次改为从右往左, 依次类推,重复2、3,直到所有元素划分完

      最终效果是比它小的放左边,比它大的放右边

5、重复1,2,3,4:将左边的一半重复1,2,3,4、,右边的一半也重复1,2,3,4、

6、接着将分得的小序列分支,再进行划分,此处用到了递归(不懂递归,自行补充食粮)

7、1,2,3的划分步骤较为难懂, 建议画图按照步骤执行一遍

# coding:utf8
def quick_sort(list_temp, start, end):
	""" 需排序列表, 开头下标, 尾部下标"""
	if start >= end:
		# 当只有一个数值进行比较那么头下标和尾下标相同,此时无需比较,跳出递归
		return

	low = start
	high = end
	mid = list_temp[start]  # 假设第一个值作为中间值

	while low < high:
		# 尾下标往前移动
		while low < high and mid <= list_temp[high]:
			high -= 1
		list_temp[low] = list_temp[high]
		# 头下标往后移动
		# 因为希望尽量保证稳定性,如果右边出现与中间值相等的,但依然后出现,这里当做是小于中间值,故需要调到后面
		while low < high and list_temp[low] < mid:
			low += 1
		list_temp[high] = list_temp[low]

	list_temp[high] = mid

	# 左边
	quick_sort(list_temp, start, high-1)
	# 右边
	quick_sort(list_temp, high+1, end)


if __name__ == '__main__':	
	# 调用
	l = [3, 0, 1, 8, 7, 2, 5, 4, 9, 6]
	quick_sort(l, 0, len(l)-1)
	print(l)

最优时间复杂度:O(nlogn)
最坏时间复杂度:O(n2)
不稳定

6、归并排序

释义:

1、将序列不断的一分为二直到只有一个元素(一个元素时肯定是个有序的序列,因为只有自己);

2、再将拆分的序列拿两个进行比较大小合并,得到一个新的有序序列;

3、再将这个有序序列拿到和下一个序列合并;

4、.......以此类推,直到将所有拆分的元素合并完

# coding:utf8
def merge_sort(li):
	"""将序列对半拆分"""
	if len(li) == 1:
		# 跳出递归,当长度为1是,即只有一个元素,直接返回自己
		return li

	mid = len(li) // 2
	left_li = li[:mid]
	right_li = li[mid:]

	# 递归调用,继续分割左边
	new_l_list = merge_sort(left_li)
	# 递归调用,继续分割右边
	new_r_list = merge_sort(right_li)

	# 将拆分的合并成新的有序列表
	new_sort_nums = merge(new_l_list, new_r_list)
	# 将新序列返回
	return new_sort_nums

def merge(left_li, right_li):
	"""将两个有序的序列合并成新的有序序列,并将这个新的有序序列返回"""
	result = []  # 新的序列
	l_index = 0  # 左边序列下标
	r_index = 0  # 右边序列下标

	while l_index < len(left_li) and r_index < len(right_li):
		if left_li[l_index] <= right_li[r_index]:
			result.append(left_li[l_index])
			l_index += 1
		else:
			result.append(right_li[r_index])
			r_index += 1

	# 跳出循环说明至少是其中的一个序列比较完了,将未比较完的直接加入到新序列中(以为两个序列分别是有序的)
	result += left_li[l_index:]
	result += right_li[r_index:]

	return result


if __name__ == '__main__':
    # 调用
    l = [3, 0, 1, 8, 7, 2, 5, 4, 9, 6]
    print(merge_sort(l))
思路运行大体步骤:
原序列:
[3, 0, 1, 8, 7, 2, 5, 4, 9, 6]
代码先左后右:
左边:                  右边:
[3, 0, 1, 8, 7]       [2, 5, 4, 9, 6]
[3, 0]   [1, 8, 7]    [2, 5]   [4, 9, 6]
[3] [0]  [1] [8, 7]   [2] [5]  [4] [9, 6]
           [8] [7]               [9] [6]
[0, 3]                [2, 5]
[7, 8]                [6, 9]
[1, 7, 8]             [4, 6, 9]
[0, 1, 3, 7, 8]       [2, 4, 5, 6, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

最坏时间复杂度:O(nlogn)
最优时间复杂度:O(nlogn)
稳定

哎唷卧槽,终于看完了!!!这可能是小伙伴们的心声,不过我也想说终于整完了。。。

目前在学习cpython,所以就贴了Python版本,希望大Python能带我飞啊~~~~~~

欢迎一起分享和交流python---->q群:556993881

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值