1.冒泡排序:
def buttle_sort(li):
for i in range(len(li)-1):
exchange= False
for j in range(len(li)-1-i):
if li[j]>li[j+1]:
li[j],li[j+1]=li[j+1],li[j]
exchange= True
if not exchange:
return
(趟是从0开始的)
数字 | 下标 | 趟 | 无序范围 | |
9 | 8 | 0 | 0-8 | |
8 | 7 | 1 | 0-7 | |
1 | 6 | 2 | 0-6 | |
7 | 5 | 《—— | 3 | 0-5 |
2 | 4 | |||
6 | 3 | |||
3 | 2 | |||
5 | 1 | |||
4 | 0 |
第二趟:
2个数(i=2)已经成序
下标6即将成序,指针最多到下标5的地方
排n个数需要n-1趟,则i的范围是0到n-1 无序区为 n-i 则i 取值n-i
由上图可知:指针最多指到 n-i-1,则 j 取值 n-i-1
优化:
一旦排序完成,再接着排就是浪费(冒泡是内排序,会按照流程排完)
2.选择排序(最小的放第前位)
简单但是错误的做法:
这种写法不好:
1.两个列表,占用内存
2.min、append都遍历了列表,而remove了元素,造成空缺,其空缺前移 都是O(n)
正确写法:
def select_sort(li):
for i in range(len(li)-1):
min_log=i #不知道谁最小,就先假定i最小,因为i是无序区的第一个元素
for j in range(i+1,len(li)): #此时的log已经代表了i本身,所以j从i+1开始
if li[j]<li[min_log]: #此if存在的意义:为将最小j赋值给min_log
min_log=j
li[i],li[min_log]=li[min_log],li[i]
#假使上面的if不成立,i还是min_log, 自己等于自己,不影响
#为什么是i与min比呢?
1.记录中j并未记录,而是给min_log赋值了
2.拿左侧无序区第一个与非第一个无序区进行比较,拿最小的放有序区
3.插入排序(玩扑克派)
定义玩扑克的正常情况:摸牌比较大,直接放在手牌的最右面
寻找6(摸牌)在457(手牌)中的位置:
开始j=3 由于li[3]>temp,摸牌小,非正常情况,j左移到2,7右移一格(5,7中间空出一格)
li[2]<temp,放在j后一位也就是j+1的位置
手牌小,摸牌大,属于正常情况: 摸到的牌比手牌j大,直接把摸到的牌插入j的右边(正常情况) 手牌大,摸牌小,要排牌(非正常的手牌右移): 进while 使大的手牌到右边,同时进行(j指针左移)到达,使摸牌比其余手牌大
def insert_sort(li):
for i in range(1,len(li)-1): #摸牌
tem=li[i] #摸牌存起来
j=i-1 #手牌的下标
while j>=0 and li[j]>tem: #走while:新摸到的牌 比 部分手牌 小,需要排牌
li[j+1]=li[j] #大的手牌向右移(实质是覆盖)
i-=1
li[j+1]=tem #摸到的牌大:不走while,直接放在手牌后一个
#指针左移了,此时的li[j+1]与上面很不同
low 逼三人组的总结:
时间复杂度都是O(n^2),都是原地排序
4.快速排序:
找出一个元素P,使P归位:小的在左边,大的在右边
用递归完成进一步排序:在大致排号的左边再选一个元素归位
大致分类框架:中间、左、右
所以怎么写partition函数呢?
第一步
拿变量将5存起来 ,左边有空位:给比5小的数准备的
从哪儿开始找呢?从右边找: 2过来
欸?右边又有空位了,放比5大的数 7过去
直到指针重合:把5放回:
def partition(li,left,right):
tem=li[left]
while left<right:
while left<right and li[right]>=tem:
right-=1
li[left]=li[right]
while left<right and li[left]<=tem:
left+=1
li[right]=li[left]
li[left]=tem
return left //返回mid的值
def quick_sork(li,left,right):
if left<right:
mid =partition(li,left,right)
quick_sork(li,left,mid-1)
quick_sork(li,mid+1,right)
非严谨分析:
logn层(往下减半),每层O(n)的复杂度,——>O(nlogn)
最坏情况:没有很理解
正序或者逆序,每次只少一个,画出的是一颗斜树
5.堆排序