冒泡-选择-插入-快速-堆-归并

在这里插入图片描述

冒泡排序

第一种

 """排序思路:列表可乱序,从第一个数开始往后查找,每次查找把左右两个数比较后交换,
 一次排序后出现一个最大值还活着最小值在最后或者最前,需要进行n-1趟,但是可以使用标记的方式,当当前这一趟列表"""
def bubble_sort(li):
    for i in range(len(li)-1):
        flag=False
        for j in range(len(li)-1-i):   #从已经排好序的找前面的数
            if li[j]>li[j+1]:         #如果都找不到后面的大于前面的,flag=False
                li[j],li[j+1]=li[j+1],li[j]
                flag=True
        if not flag:   
        #当进入循环,发生交换,说明还没结束,循环继续,当not flag =True,说明flag=False,说明进入第二层循环后没有交换
            break
    return li
li=[96,3,4,6984,13,468]
print(bubble_sort(li))

选择排序

第一种

#排序思路:新建列表,每次从旧列表中找到最小值加入新列表,删除旧列表最小的值,反复
def choose_sort_simple(li):
    list=[]
    for i in range(len(li)):
        min_val=min(li)
        list.append(min_val)      #O(n)
        li.remove(min_val)     #O(n)  
    return list
print(choose_sort_simple([96,3,4,6984,13,468]))
缺点:min和remove都是不仅仅是O(n),使用新列表,不是原地排序

第二种

#排序思路:把第一当作最小的,与后面的对比,小于它就交换,循环n-1趟
def choose_sort(li):
    """由于傻瓜式选择排序花费大量时间复杂度,所以此次使用交换方法
    默认第一个为最小值,无序区不断变小直至为0,有序区不断变大,直至有序"""
    for i in range(len(li)-1):
        min_val=i
        for j in range(i+1,len(li)):
            if li[j]<li[min_val]:
                min_val=j
        li[i],li[min_val]=li[min_val],li[i]
    return li
print(choose_sort([96, 3, 4, 6984, 13, 468]))

插入排序

"""排序思路:1打牌思路,手中本身仅有一张牌,总共的牌位有13位,把第二张牌当作摸到的第一张插入到手中,和手中的牌按顺序依次比较
使用列表来叙述如下:例如一个长度为10的列表,第一张牌作为手中的已知牌,从摸到的第一张牌也是就要排序的第一张牌开始,
依次与前面的作比较,查找插入的位置,如果摸到的牌小于手中的牌,手中的牌往后移既赋值,摸到的牌继续往前寻找插入位置,
循环满足手中牌的下标大于0并且手中的牌最大位置上的值比摸到的大"""
def insert_sort(li):
    for i in range(1,len(li)):   #i表示摸到的牌的下标
        tmp=li[i]
        j=i-1 #j表示当前手中的牌的下标
        #如果j这张牌比摸到的小,插到右边,第二种j=0这张牌比手里的牌要小
        while j>=0 and li[j] >tmp:
            li[j+1]=li[j]
            j-=1
        li[j+1]=tmp
    return li
print(insert_sort([3,2,5,84,89,46,1,5]))

!!!注释介绍
在这里插入图片描述

快速排序

#排序思路:默认第一为最小,右小默认移左边,左小默认移右边,最后默认放回,不断操作为最快
def quick_sort(li,left,right):
    while left<right:
        tmp=li[left]     #把第一位数当作对比的数
        while left<right and li[right]>=tmp:   #从右边最后一个数开始,小于对比数放左边
            right-=1             #指针往左移
        li[left]=li[right]       #移动
        while left<right and li[left]<=tmp:    #同理,左边的往右移动
            left+=1
        li[right]=li[left]
    li[left]=tmp			#把中间那个数放回它该放的位置,即左边小于它,右边大于它
    return left

def _quick_sort(li,left,right):
    if left<right:
        mid = quick_sort(li,left,right)
        _quick_sort(li,left,mid-1)
        _quick_sort(li,mid+1,right)

li=[random.randint(0,100) for _ in range(10)]
_quick_sort(li,0,len(li)-1)
print(li)

全在图里
![在这里插入图片描述](https://img-blog.csdnimg.cn/bc983519fe1c493a874fe27e4041d521.jpeg#pic_center在这里插入图片描述

堆排序

"""
排序思路:堆排序拿大根堆为例,是一个不断建初堆,调整堆的过程
建初堆:大根堆就是将树变成父亲节点永远大于左右孩子节点的堆
调整堆:大根堆把堆顶输出,最后一个元素移到堆顶,从新建堆
"""
def sift(li,low,high):
	"""
	:param li:
    :param low: 堆的根节点位置
    :param high: 堆的最后一个元素的位置
    :return:
	"""
	i=low   #i是最开始指向的节点位置
	j=2*i+1    #先看左孩子
	tmp= li[low]   # 把堆顶存起来
	while j<=high:    #只要堆顶下面的左孩子有数,说明一致没结束
		if j+1<=high and li[j+1]>li[j]:   #右孩子有并且比较大
			j=j+1   #j指向右孩子
		if li[j]>tmp:   #孩子的值比堆顶大
			li[i]=li[j]    #孩子的值移上去
			i=j       #i指向刚刚j的位置 
			j=2*i+1    #j变成了它现在i的左孩子
		else:        #否则堆顶更大,tmp放在i的位置上
			li[i]=tmp      #原先的值就较大,直接把tmp放到某一级大于其左右孩子的值上
			break
	else:
		li[i]=tmp   #tmp放到叶子节点上
def heap_sort(li):
    n=len(li)
    for i in range((n-2)//2,-1,-1):  #从0到最后一个节点的父节点
        #i表示建堆的时候调整堆的下标
        sift(li,i,n-1)  #n-1表示最后一个元素的下标
    #建堆完成
    #进入排序阶段
    for i in range(n-1,-1,-1):
        # i 指向当前堆的最后一个元素
        li[0],li[i]=li[i],li[0]  #把最后一个元素移到堆顶,堆顶元素存起来
        sift(li,0,i-1)  #i-1是新的high(新的最后一个元素的位置)

li=[8,2,5,6,1,4]
import random
#random.shuffle(li)
heap_sort(li)
print(li)

归并排序

"""
sort()中使用的就是这种排序,将排序两两分组
例如16个数,先 8 8分,8再分4 4 4再分2 2 ,此时2开始排序,再2 2 合并到4 ,然后4 4 排序,最后归并
"""
def merch_sort(li,low,mid,high):
    i=low    #合并后排序位置中最左边的
    j=mid+1   #合并后,后面列表中的第一个位置
    ltmp=[]   #新建一个列表,所以空间复杂度与其他排序有所不同  O(n)
    while i<=mid and j<=high:
        if li[i]<=li[j]:  #左边的第一个小于右边的第一个
            ltmp.append(li[i])
            i+=1
        else:
            ltmp.append(li[j])
            j+=1
    #由于总有一边的序列先排序完成,所以要独自对后面的数进行排序
    while i<=mid:
        ltmp.append(li[i])
        i+=1
    while j<=high:
        ltmp.append(li[j])
        j+=1
    #最后把列表放会原列表中
    li[low:high+1]=ltmp
    return li

def mergesort(li,low,high):
    if low<high:
        mid=(low+high)//2
        mergesort(li,low,mid) 
        mergesort(li,mid+1,high)
        merch_sort(li,low,mid,high)
# li=[2,3,5,7,1,4,8,9]
# print(merch_sort(li,0,3,7))
li=[1,6486,46,1651,65,165,15,132148,746,43,135,1,53]
print(mergesort(li,0,len(li)-1))
print(li)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值